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 }