View Javadoc

1   // WARNING: This file was automatically generated. Do not edit it directly,
2   //          or you will lose your changes.
3   
4   /*
5    * Licensed to the Apache Software Foundation (ASF) under one
6    * or more contributor license agreements.  See the NOTICE file
7    * distributed with this work for additional information
8    * regarding copyright ownership.  The ASF licenses this file
9    * to you under the Apache License, Version 2.0 (the
10   * "License"); you may not use this file except in compliance
11   * with the License.  You may obtain a copy of the License at
12   *
13   *   http://www.apache.org/licenses/LICENSE-2.0
14   *
15   * Unless required by applicable law or agreed to in writing,
16   * software distributed under the License is distributed on an
17   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18   * KIND, either express or implied.  See the License for the
19   * specific language governing permissions and limitations
20   * under the License.
21  */
22  package org.apache.myfaces.trinidad.component;
23  
24  import java.io.IOException;
25  import javax.el.MethodExpression;
26  import javax.faces.component.UIComponent;
27  import javax.faces.context.FacesContext;
28  import javax.faces.el.MethodBinding;
29  import javax.faces.event.AbortProcessingException;
30  import javax.faces.event.FacesEvent;
31  import javax.faces.event.PhaseId;
32  import org.apache.myfaces.trinidad.bean.FacesBean;
33  import org.apache.myfaces.trinidad.bean.PropertyKey;
34  import org.apache.myfaces.trinidad.event.RangeChangeEvent;
35  import org.apache.myfaces.trinidad.event.RangeChangeListener;
36  import org.apache.myfaces.trinidad.model.CollectionModel;
37  import org.apache.myfaces.trinidad.model.ModelUtils;
38  import org.apache.myfaces.trinidad.util.ComponentUtils;
39  
40  /**
41   *
42   * UIXSelectRange is a base abstraction for 
43   *           components that select a
44   *           range, e.g, 5 - 10 of 50.
45   *
46   * <h4>Events:</h4>
47   * <table border="1" width="100%" cellpadding="3" summary="">
48   * <tr bgcolor="#CCCCFF" class="TableHeadingColor">
49   * <th align="left">Type</th>
50   * <th align="left">Phases</th>
51   * <th align="left">Description</th>
52   * </tr>
53   * <tr class="TableRowColor">
54   * <td valign="top"><code>org.apache.myfaces.trinidad.event.RangeChangeEvent</code></td>
55   * <td valign="top" nowrap>Any<br>Phase<br>Invoke<br>Application</td>
56   * <td valign="top">The range change event is delivered when the user
57                         navigates.</td>
58   * </tr>
59   * <tr class="TableRowColor">
60   * <td valign="top"><code>org.apache.myfaces.trinidad.event.AttributeChangeEvent</code></td>
61   * <td valign="top" nowrap>Invoke<br>Application<br>Apply<br>Request<br>Values</td>
62   * <td valign="top">Event delivered to describe an attribute change.  Attribute change events are not delivered for any programmatic change to a property.  They are only delivered when a renderer changes a property without the application's specific request.  An example of an attribute change event might include the width of a column that supported client-side resizing.</td>
63   * </tr>
64   * </table>
65   */
66  public class UIXSelectRange extends UIXComponentBase
67  {
68    static public final FacesBean.Type TYPE = new FacesBean.Type(
69      UIXComponentBase.TYPE);
70    static public final PropertyKey VAR_KEY =
71      TYPE.registerKey("var", String.class, PropertyKey.CAP_NOT_BOUND);
72    static public final PropertyKey IMMEDIATE_KEY =
73      TYPE.registerKey("immediate", Boolean.class, Boolean.FALSE);
74    static public final PropertyKey RANGE_CHANGE_LISTENER_KEY =
75      TYPE.registerKey("rangeChangeListener", MethodExpression.class);
76    static public final PropertyKey VALUE_KEY =
77      TYPE.registerKey("value");
78    static public final PropertyKey ROWS_KEY =
79      TYPE.registerKey("rows", Integer.class, Integer.valueOf(25));
80    static public final PropertyKey FIRST_KEY =
81      TYPE.registerKey("first", Integer.class, Integer.valueOf(0));
82    static public final String RANGE_LABEL_FACET = "rangeLabel";
83  
84    static public final String COMPONENT_FAMILY =
85      "org.apache.myfaces.trinidad.SelectRange";
86    static public final String COMPONENT_TYPE =
87      "org.apache.myfaces.trinidad.SelectRange";
88  
89    /**
90     * Construct an instance of the UIXSelectRange.
91     */
92    public UIXSelectRange()
93    {
94      super("org.apache.myfaces.trinidad.ChoiceBar");
95    }
96    
97    @Deprecated
98    public void setRangeChangeListener(MethodBinding binding)
99    {
100     setRangeChangeListener(adaptMethodBinding(binding));
101   }
102 
103   @Override
104   public void encodeBegin(FacesContext context) throws IOException
105   {
106     _flushCachedDataModel();
107     super.encodeBegin(context);
108   }
109 
110   @Override
111   public void broadcast(FacesEvent event) throws AbortProcessingException
112   {
113     // Notify the specified RangeChanged listener method (if any)
114     if (event instanceof RangeChangeEvent)
115     {
116       RangeChangeEvent gtEvent = (RangeChangeEvent)event;
117       // update first when the event is delivered
118       setFirst(gtEvent.getNewStart());
119 
120       broadcastToMethodExpression(event, getRangeChangeListener());
121     }
122 
123     // Perform standard superclass processing
124     super.broadcast(event);
125   }
126   
127   /**
128    * * We don't want to update model if we have validation errors
129    * on the page, so if not immediate, queue the event in
130    * INVOKE_APPLICATION phase.
131    */
132   @Override
133   public void queueEvent(FacesEvent e)
134   {
135     if ((e instanceof RangeChangeEvent) && (e.getSource() == this))
136     {
137       if (isImmediate())
138       {
139         e.setPhaseId(PhaseId.ANY_PHASE);
140       }
141       else
142       {
143         e.setPhaseId(PhaseId.INVOKE_APPLICATION);
144       }
145     }
146 
147     super.queueEvent(e);
148   }
149 
150   /**
151    * Makes a row current.
152    * @see CollectionModel#setRowIndex
153    * @param rowIndex the zero-based row-index of the row that should be made
154    * current. Use -1 to clear the current row.
155    */
156   public final void setRowIndex(int rowIndex)
157   {
158     _getDataModel().setRowIndex(rowIndex);
159   }
160 
161   /**
162    * @see CollectionModel#getRowIndex
163    * @return the zero-based row-index of the current row, or -1
164    *  if now row is current.
165    */
166   public final int getRowIndex()
167   {
168     return _getDataModel().getRowIndex();
169   }
170 
171   /**
172    * Gets the total number of rows in this table.
173    * @see CollectionModel#getRowCount
174    * @return -1 if the total number is not known.
175    */
176   public final int getRowCount()
177   {
178     return _getDataModel().getRowCount();
179   }
180 
181   /**
182   * Checks to see if the current row is available. This is useful when the
183   * total number of rows is not known.
184   * @see CollectionModel#isRowAvailable
185   * @return true iff the current row is available.
186   */
187    public final boolean isRowAvailable()
188    {
189      return _getDataModel().isRowAvailable();
190    }
191 
192   /**
193   * Checks to see if the given row is available. This is useful when the
194   * total number of rows is not known.
195   * @see CollectionModel#isRowAvailable(int)
196   * @param rowIndex identifies the row to check
197   * @return true iff the current row is available.
198   */
199    public final boolean isRowAvailable(int rowIndex)
200    {
201      return _getDataModel().isRowAvailable(rowIndex);
202    }
203 
204   /**
205    * Gets the data for the current row.
206    * @see CollectionModel#getRowData
207    * @return null if the current row is unavailable
208    */
209   public final Object getRowData()
210   {
211     CollectionModel model = _getDataModel();
212     // we need to call isRowAvailable() here because the 1.0 sun RI was
213     // throwing exceptions when getRowData() was called with rowIndex=-1
214     return model.isRowAvailable() ? model.getRowData() : null;
215   }
216 
217   /**
218    * Gets the data for the current row.
219    * @param rowIndex identifies the row to get data from
220    * @see CollectionModel#getRowData(int)
221    * @return null if the current row is unavailable
222    */
223   public final Object getRowData(int rowIndex)
224   {
225     CollectionModel model = _getDataModel();
226     // we need to call isRowAvailable() here because the 1.0 sun RI was
227     // throwing exceptions when getRowData() was called with rowIndex=-1
228     return model.isRowAvailable(rowIndex) ? model.getRowData(rowIndex) : null;
229   }
230 
231   private CollectionModel _getDataModel()
232   {
233     if (_dataModel == null)
234     {
235       Object value = getValue();
236 
237       _dataModel = ModelUtils.toCollectionModel(value);
238 
239     }
240 
241     return _dataModel;
242   }
243 
244   //
245   // Flush the cached data model, if needed
246   //
247   private void _flushCachedDataModel()
248   {
249 
250      _dataModel = null;
251 
252   }
253 
254   private transient CollectionModel   _dataModel = null;
255 
256   /**
257    * use to customize the label of each range selection.
258    */
259   final public UIComponent getRangeLabel()
260   {
261     return getFacet(RANGE_LABEL_FACET);
262   }
263 
264   /**
265    * use to customize the label of each range selection.
266    */
267   @SuppressWarnings("unchecked")
268   final public void setRangeLabel(UIComponent rangeLabelFacet)
269   {
270     getFacets().put(RANGE_LABEL_FACET, rangeLabelFacet);
271   }
272 
273   /**
274    * Gets the name of the EL variable that provides access to the "start"
275    *               and "end" variables that point to the start and end row in
276    *               the each range from the data model. This can be used to customize
277    *               the range text.
278    *
279    * @return  the new var value
280    */
281   final public String getVar()
282   {
283     return ComponentUtils.resolveString(getProperty(VAR_KEY));
284   }
285 
286   /**
287    * Sets the name of the EL variable that provides access to the "start"
288    *               and "end" variables that point to the start and end row in
289    *               the each range from the data model. This can be used to customize
290    *               the range text.
291    * 
292    * @param var  the new var value
293    */
294   final public void setVar(String var)
295   {
296     setProperty(VAR_KEY, (var));
297   }
298 
299   /**
300    * Gets whether data validation 
301    *           should be skipped when range change
302    *           events are generated by this component.
303    * 
304    *           When immediate is false (the default), events will
305    *           be delivered during the Invoke Application phase, which
306    *           will trigger validation.  When set to true,  events
307    *           will be executed during the Apply Request Values phase.
308    *
309    * @return  the new immediate value
310    */
311   final public boolean isImmediate()
312   {
313     return ComponentUtils.resolveBoolean(getProperty(IMMEDIATE_KEY), false);
314   }
315 
316   /**
317    * Sets whether data validation 
318    *           should be skipped when range change
319    *           events are generated by this component.
320    * 
321    *           When immediate is false (the default), events will
322    *           be delivered during the Invoke Application phase, which
323    *           will trigger validation.  When set to true,  events
324    *           will be executed during the Apply Request Values phase.
325    * 
326    * @param immediate  the new immediate value
327    */
328   final public void setImmediate(boolean immediate)
329   {
330     setProperty(IMMEDIATE_KEY, immediate ? Boolean.TRUE : Boolean.FALSE);
331   }
332 
333   /**
334    * Gets a method reference to a rangeChange listener that
335    *          will be called when a new range is selected.
336    *
337    * @return  the new rangeChangeListener value
338    */
339   final public MethodExpression getRangeChangeListener()
340   {
341     return (MethodExpression)getProperty(RANGE_CHANGE_LISTENER_KEY);
342   }
343 
344   /**
345    * Sets a method reference to a rangeChange listener that
346    *          will be called when a new range is selected.
347    * 
348    * @param rangeChangeListener  the new rangeChangeListener value
349    */
350   final public void setRangeChangeListener(MethodExpression rangeChangeListener)
351   {
352     setProperty(RANGE_CHANGE_LISTENER_KEY, (rangeChangeListener));
353   }
354 
355   /**
356    * Gets <html> the data model being used by this component.
357    * The specific model class is
358    *         <code>org.apache.myfaces.trinidad.model.CollectionModel</code>.
359    * 
360    *         You may also use other model instances, e.g.,  
361    *         <code>java.util.List</code>  ,
362    *         array, and  <code>javax.faces.model.DataModel</code>.
363    *         This component will automatically convert the instance
364    *         into a <code>CollectionModel</code>.</html>
365    *
366    * @return  the new value value
367    */
368   final public Object getValue()
369   {
370     return getProperty(VALUE_KEY);
371   }
372 
373   /**
374    * Sets <html> the data model being used by this component.
375    * The specific model class is
376    *         <code>org.apache.myfaces.trinidad.model.CollectionModel</code>.
377    * 
378    *         You may also use other model instances, e.g.,  
379    *         <code>java.util.List</code>  ,
380    *         array, and  <code>javax.faces.model.DataModel</code>.
381    *         This component will automatically convert the instance
382    *         into a <code>CollectionModel</code>.</html>
383    * 
384    * @param value  the new value value
385    */
386   final public void setValue(Object value)
387   {
388     setProperty(VALUE_KEY, (value));
389   }
390 
391   /**
392    * Gets the maximum number of rows to display in a single range of rows.
393    * Some ranges might have fewer
394    * than the number of rows specified by this attribute (eg: the last range
395    * might have an insufficient number of rows).
396    * To display all rows at once, set this attribute to 0.
397    *
398    * @return  the new rows value
399    */
400   final public int getRows()
401   {
402     return ComponentUtils.resolveInteger(getProperty(ROWS_KEY), 25);
403   }
404 
405   /**
406    * Sets the maximum number of rows to display in a single range of rows.
407    * Some ranges might have fewer
408    * than the number of rows specified by this attribute (eg: the last range
409    * might have an insufficient number of rows).
410    * To display all rows at once, set this attribute to 0.
411    * 
412    * @param rows  the new rows value
413    */
414   final public void setRows(int rows)
415   {
416     setProperty(ROWS_KEY, Integer.valueOf(rows));
417   }
418 
419   /**
420    * Gets the index of the first row in the currently range of rows.
421    * This index is zero-based. This attribute is used to control
422    * which range of rows to display to the user.
423    *
424    * @return  the new first value
425    */
426   final public int getFirst()
427   {
428     return ComponentUtils.resolveInteger(getProperty(FIRST_KEY), 0);
429   }
430 
431   /**
432    * Sets the index of the first row in the currently range of rows.
433    * This index is zero-based. This attribute is used to control
434    * which range of rows to display to the user.
435    * 
436    * @param first  the new first value
437    */
438   final public void setFirst(int first)
439   {
440     setProperty(FIRST_KEY, Integer.valueOf(first));
441   }
442 
443   /**
444    * Adds a rangeChange listener.
445    *
446    * @param listener  the rangeChange listener to add
447    */
448   final public void addRangeChangeListener(
449     RangeChangeListener listener)
450   {
451     addFacesListener(listener);
452   }
453 
454   /**
455    * Removes a rangeChange listener.
456    *
457    * @param listener  the rangeChange listener to remove
458    */
459   final public void removeRangeChangeListener(
460     RangeChangeListener listener)
461   {
462     removeFacesListener(listener);
463   }
464 
465   /**
466    * Returns an array of attached rangeChange listeners.
467    *
468    * @return  an array of attached rangeChange listeners.
469    */
470   final public RangeChangeListener[] getRangeChangeListeners()
471   {
472     return (RangeChangeListener[])getFacesListeners(RangeChangeListener.class);
473   }
474 
475   @Override
476   public String getFamily()
477   {
478     return COMPONENT_FAMILY;
479   }
480 
481   @Override
482   protected FacesBean.Type getBeanType()
483   {
484     return TYPE;
485   }
486 
487   /**
488    * Construct an instance of the UIXSelectRange.
489    */
490   protected UIXSelectRange(
491     String rendererType
492     )
493   {
494     super(rendererType);
495   }
496 
497   static
498   {
499     TYPE.lockAndRegister("org.apache.myfaces.trinidad.SelectRange","org.apache.myfaces.trinidad.ChoiceBar");
500   }
501 }