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.core.layout;
23  
24  import java.util.Arrays;
25  import java.util.Collection;
26  import java.util.Collections;
27  import java.util.List;
28  import java.util.Map;
29  import javax.faces.component.UIComponent;
30  import javax.faces.component.behavior.ClientBehavior;
31  import javax.faces.component.behavior.ClientBehaviorHolder;
32  import javax.faces.component.visit.VisitCallback;
33  import javax.faces.component.visit.VisitContext;
34  import javax.faces.component.visit.VisitContextWrapper;
35  import javax.faces.component.visit.VisitHint;
36  import javax.faces.component.visit.VisitResult;
37  import javax.faces.event.AbortProcessingException;
38  import javax.faces.event.FacesEvent;
39  import org.apache.myfaces.trinidad.bean.FacesBean;
40  import org.apache.myfaces.trinidad.bean.PropertyKey;
41  import org.apache.myfaces.trinidad.component.FlattenedComponent;
42  import org.apache.myfaces.trinidad.component.UIXPanel;
43  import org.apache.myfaces.trinidad.component.UIXShowDetail;
44  import org.apache.myfaces.trinidad.event.DisclosureEvent;
45  import org.apache.myfaces.trinidad.util.ComponentUtils;
46  
47  /**
48   *
49   * The panelAccordion control can be used to
50   * display a group of contents belonging to a showDetailItem.  It supports
51   * both a one-item-at-a-time mode - the default - or multiple-items-at-a-time.
52   * The latter can be enabled by setting "discloseMany" to true.  Visually,
53   * an accordion looks like a series of accordion bars,
54   * with panels below the bar representing disclosed showDetailItem children.
55   *
56   * <h4>Events:</h4>
57   * <table border="1" width="100%" cellpadding="3" summary="">
58   * <tr bgcolor="#CCCCFF" class="TableHeadingColor">
59   * <th align="left">Type</th>
60   * <th align="left">Phases</th>
61   * <th align="left">Description</th>
62   * </tr>
63   * <tr class="TableRowColor">
64   * <td valign="top"><code>org.apache.myfaces.trinidad.event.AttributeChangeEvent</code></td>
65   * <td valign="top" nowrap>Invoke<br>Application<br>Apply<br>Request<br>Values</td>
66   * <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>
67   * </tr>
68   * </table>
69   */
70  public class CorePanelAccordion extends UIXPanel
71                                  implements ClientBehaviorHolder
72  {
73    static public final FacesBean.Type TYPE = new FacesBean.Type(
74      UIXPanel.TYPE);
75    static public final PropertyKey INLINE_STYLE_KEY =
76      TYPE.registerKey("inlineStyle", String.class);
77    static public final PropertyKey STYLE_CLASS_KEY =
78      TYPE.registerKey("styleClass", String.class);
79    static public final PropertyKey SHORT_DESC_KEY =
80      TYPE.registerKey("shortDesc", String.class);
81    static public final PropertyKey PARTIAL_TRIGGERS_KEY =
82      TYPE.registerKey("partialTriggers", String[].class, null, 0, PropertyKey.Mutable.RARELY);
83    static public final PropertyKey ONCLICK_KEY =
84      TYPE.registerKey("onclick", String.class);
85    static public final PropertyKey ONDBLCLICK_KEY =
86      TYPE.registerKey("ondblclick", String.class);
87    static public final PropertyKey ONMOUSEDOWN_KEY =
88      TYPE.registerKey("onmousedown", String.class);
89    static public final PropertyKey ONMOUSEUP_KEY =
90      TYPE.registerKey("onmouseup", String.class);
91    static public final PropertyKey ONMOUSEOVER_KEY =
92      TYPE.registerKey("onmouseover", String.class);
93    static public final PropertyKey ONMOUSEMOVE_KEY =
94      TYPE.registerKey("onmousemove", String.class);
95    static public final PropertyKey ONMOUSEOUT_KEY =
96      TYPE.registerKey("onmouseout", String.class);
97    static public final PropertyKey ONKEYPRESS_KEY =
98      TYPE.registerKey("onkeypress", String.class);
99    static public final PropertyKey ONKEYDOWN_KEY =
100     TYPE.registerKey("onkeydown", String.class);
101   static public final PropertyKey ONKEYUP_KEY =
102     TYPE.registerKey("onkeyup", String.class);
103   static public final PropertyKey DISCLOSE_NONE_KEY =
104     TYPE.registerKey("discloseNone", Boolean.class, Boolean.FALSE);
105   static public final PropertyKey DISCLOSE_MANY_KEY =
106     TYPE.registerKey("discloseMany", Boolean.class, Boolean.FALSE);
107 
108   static public final String COMPONENT_FAMILY =
109     "org.apache.myfaces.trinidad.Panel";
110   static public final String COMPONENT_TYPE =
111     "org.apache.myfaces.trinidad.CorePanelAccordion";
112   // Supported client events for client behaviors:
113   private final static Collection<String> _EVENT_NAMES = Collections.unmodifiableCollection(
114     Arrays.asList(
115       "click", "dblclick", "mousedown", "mouseup", "mouseover", "mousemove",
116       "mouseout", "keypress", "keydown", "keyup"
117     ));
118 
119   /**
120    * Construct an instance of the CorePanelAccordion.
121    */
122   public CorePanelAccordion()
123   {
124     super("org.apache.myfaces.trinidad.Accordion");
125   }
126   
127   /**
128    * Queues an event recursively to the root component.
129    * @param event
130    * @throws javax.faces.event.AbortProcessingException
131    */
132   @Override
133   public void queueEvent(FacesEvent event)
134     throws AbortProcessingException
135   {
136     // For a "show-one" panel accordion, handle an "expanding"
137     // DisclosureEvent specifically, only if the source
138     // is one of its immediate children
139     if ((event instanceof DisclosureEvent) &&
140         !isDiscloseMany() &&
141         (this == event.getComponent().getParent()) &&
142         ((DisclosureEvent) event).isExpanded())
143 
144     {
145       for (UIComponent comp : ((List<UIComponent>) getChildren()))
146       {
147         // Skip over the show detail that is the source of this event
148         if (comp == event.getComponent())
149           continue;
150 
151         if (comp instanceof UIXShowDetail)
152         {
153           UIXShowDetail showDetail = (UIXShowDetail) comp;
154           // Queue an event to hide the currently expanded showDetail
155           if (showDetail.isDisclosed())
156             (new DisclosureEvent(showDetail, false)).queue();
157         }
158       }
159     }
160     super.queueEvent(event);
161   }
162 
163   @Override
164   public boolean visitTree(
165     VisitContext  visitContext,
166     VisitCallback callback)
167   {
168     if (visitContext.getHints().contains(VisitHint.SKIP_UNRENDERED) &&
169      !isDiscloseMany())
170     {
171       // Filter which children to be visited so that only one show detail
172       // is visited for this accordion
173       visitContext = new PartialVisitContext(visitContext);
174     }
175     return super.visitTree(visitContext, callback);
176   }
177 
178   protected boolean isChildSelected(
179     UIXShowDetail component)
180   {
181     return component.isDisclosed();
182   }
183 
184   private class PartialVisitContext
185     extends VisitContextWrapper
186   {
187     PartialVisitContext(
188       VisitContext wrapped)
189     {
190       _wrapped = wrapped;
191     }
192 
193     public VisitContext getWrapped()
194     {
195       return _wrapped;
196     }
197 
198     @Override
199     public VisitResult invokeVisitCallback(
200       UIComponent   component,
201       VisitCallback visitCallback)
202     {
203       if (component instanceof UIXShowDetail)
204       {
205         UIXShowDetail showDetail = (UIXShowDetail)component;
206         if (_isShowDetailForCurrentComponent(showDetail))
207         {
208           if (_foundItemToRender || !isChildSelected(showDetail))
209           {
210             // We already visited the one to be shown
211             return VisitResult.REJECT;
212           }
213           else
214           {
215             _foundItemToRender = true;
216           }
217         }
218       }
219 
220       return super.invokeVisitCallback(component, visitCallback);
221     }
222 
223     private boolean _isShowDetailForCurrentComponent(
224       UIXShowDetail showDetail)
225     {
226       for (UIComponent parent = showDetail.getParent(); parent != null;
227            parent = parent.getParent())
228       {
229         if (parent == CorePanelAccordion.this)
230         {
231           return true;
232         }
233 
234         if (parent instanceof FlattenedComponent &&
235           ((FlattenedComponent)parent).isFlatteningChildren(getFacesContext()))
236         {
237           continue;
238         }
239 
240         // The first-non flattened component is not the show one, do not filter it
241         return false;
242       }
243 
244       return false;
245     }
246 
247     private boolean      _foundItemToRender;
248     private VisitContext _wrapped;
249   }
250 
251   /**
252    * Gets the CSS styles to use for this component.
253    *
254    * @return  the new inlineStyle value
255    */
256   final public String getInlineStyle()
257   {
258     return ComponentUtils.resolveString(getProperty(INLINE_STYLE_KEY));
259   }
260 
261   /**
262    * Sets the CSS styles to use for this component.
263    * 
264    * @param inlineStyle  the new inlineStyle value
265    */
266   final public void setInlineStyle(String inlineStyle)
267   {
268     setProperty(INLINE_STYLE_KEY, (inlineStyle));
269   }
270 
271   /**
272    * Gets a CSS style class to use for this component.
273    *
274    * @return  the new styleClass value
275    */
276   final public String getStyleClass()
277   {
278     return ComponentUtils.resolveString(getProperty(STYLE_CLASS_KEY));
279   }
280 
281   /**
282    * Sets a CSS style class to use for this component.
283    * 
284    * @param styleClass  the new styleClass value
285    */
286   final public void setStyleClass(String styleClass)
287   {
288     setProperty(STYLE_CLASS_KEY, (styleClass));
289   }
290 
291   /**
292    * Gets The short description of the component. This text is commonly used by user agents to display tooltip help text.
293    *
294    * @return  the new shortDesc value
295    */
296   final public String getShortDesc()
297   {
298     return ComponentUtils.resolveString(getProperty(SHORT_DESC_KEY));
299   }
300 
301   /**
302    * Sets The short description of the component. This text is commonly used by user agents to display tooltip help text.
303    * 
304    * @param shortDesc  the new shortDesc value
305    */
306   final public void setShortDesc(String shortDesc)
307   {
308     setProperty(SHORT_DESC_KEY, (shortDesc));
309   }
310 
311   /**
312    * Gets the IDs of the components that should trigger a partial update.
313    *         <p>
314    *         This component will listen on the trigger components. If one of the
315    *         trigger components receives an event that will cause it to update
316    *         in some way, this component will request to be updated too.</p>
317    *         <p>
318    *         Separate multiple triggers with a space. e.g., partialTriggers="cmp1 cmp2"
319    *         </p>
320    *         <p>
321    *         Identifiers must account for NamingContainers.  You can use a single colon to start the search from the root,
322    *         or use multiple colons to move up through the NamingContainer. For example,
323    *         "::" will pop out of this component's naming container (it pops out of itself if it is a naming container), 
324    *         ":::" will pop out of two naming containers, etc. The search for
325    *         the partialTrigger begins from there. e.g., partialTriggers=":::commandButton1" the search begins for the 
326    *         component with id = commandButton1 after popping out of two naming containers relative to this component.
327    *         To go into naming containers, you separate the naming containers with ':', e.g.,partialTriggers= "nc1:nc2:nc3:componentId".</p>
328    *
329    * @return  the new partialTriggers value
330    */
331   final public String[] getPartialTriggers()
332   {
333     return (String[])getProperty(PARTIAL_TRIGGERS_KEY);
334   }
335 
336   /**
337    * Sets the IDs of the components that should trigger a partial update.
338    *         <p>
339    *         This component will listen on the trigger components. If one of the
340    *         trigger components receives an event that will cause it to update
341    *         in some way, this component will request to be updated too.</p>
342    *         <p>
343    *         Separate multiple triggers with a space. e.g., partialTriggers="cmp1 cmp2"
344    *         </p>
345    *         <p>
346    *         Identifiers must account for NamingContainers.  You can use a single colon to start the search from the root,
347    *         or use multiple colons to move up through the NamingContainer. For example,
348    *         "::" will pop out of this component's naming container (it pops out of itself if it is a naming container), 
349    *         ":::" will pop out of two naming containers, etc. The search for
350    *         the partialTrigger begins from there. e.g., partialTriggers=":::commandButton1" the search begins for the 
351    *         component with id = commandButton1 after popping out of two naming containers relative to this component.
352    *         To go into naming containers, you separate the naming containers with ':', e.g.,partialTriggers= "nc1:nc2:nc3:componentId".</p>
353    * 
354    * @param partialTriggers  the new partialTriggers value
355    */
356   final public void setPartialTriggers(String[] partialTriggers)
357   {
358     setProperty(PARTIAL_TRIGGERS_KEY, (partialTriggers));
359   }
360 
361   /**
362    * Gets an onclick Javascript handler.
363    *
364    * @return  the new onclick value
365    */
366   final public String getOnclick()
367   {
368     return ComponentUtils.resolveString(getProperty(ONCLICK_KEY));
369   }
370 
371   /**
372    * Sets an onclick Javascript handler.
373    * 
374    * @param onclick  the new onclick value
375    */
376   final public void setOnclick(String onclick)
377   {
378     setProperty(ONCLICK_KEY, (onclick));
379   }
380 
381   /**
382    * Gets an ondblclick Javascript handler.
383    *
384    * @return  the new ondblclick value
385    */
386   final public String getOndblclick()
387   {
388     return ComponentUtils.resolveString(getProperty(ONDBLCLICK_KEY));
389   }
390 
391   /**
392    * Sets an ondblclick Javascript handler.
393    * 
394    * @param ondblclick  the new ondblclick value
395    */
396   final public void setOndblclick(String ondblclick)
397   {
398     setProperty(ONDBLCLICK_KEY, (ondblclick));
399   }
400 
401   /**
402    * Gets an onmousedown Javascript handler.
403    *
404    * @return  the new onmousedown value
405    */
406   final public String getOnmousedown()
407   {
408     return ComponentUtils.resolveString(getProperty(ONMOUSEDOWN_KEY));
409   }
410 
411   /**
412    * Sets an onmousedown Javascript handler.
413    * 
414    * @param onmousedown  the new onmousedown value
415    */
416   final public void setOnmousedown(String onmousedown)
417   {
418     setProperty(ONMOUSEDOWN_KEY, (onmousedown));
419   }
420 
421   /**
422    * Gets an onmouseup Javascript handler.
423    *
424    * @return  the new onmouseup value
425    */
426   final public String getOnmouseup()
427   {
428     return ComponentUtils.resolveString(getProperty(ONMOUSEUP_KEY));
429   }
430 
431   /**
432    * Sets an onmouseup Javascript handler.
433    * 
434    * @param onmouseup  the new onmouseup value
435    */
436   final public void setOnmouseup(String onmouseup)
437   {
438     setProperty(ONMOUSEUP_KEY, (onmouseup));
439   }
440 
441   /**
442    * Gets an onmouseover Javascript handler.
443    *
444    * @return  the new onmouseover value
445    */
446   final public String getOnmouseover()
447   {
448     return ComponentUtils.resolveString(getProperty(ONMOUSEOVER_KEY));
449   }
450 
451   /**
452    * Sets an onmouseover Javascript handler.
453    * 
454    * @param onmouseover  the new onmouseover value
455    */
456   final public void setOnmouseover(String onmouseover)
457   {
458     setProperty(ONMOUSEOVER_KEY, (onmouseover));
459   }
460 
461   /**
462    * Gets an onmousemove Javascript handler.
463    *
464    * @return  the new onmousemove value
465    */
466   final public String getOnmousemove()
467   {
468     return ComponentUtils.resolveString(getProperty(ONMOUSEMOVE_KEY));
469   }
470 
471   /**
472    * Sets an onmousemove Javascript handler.
473    * 
474    * @param onmousemove  the new onmousemove value
475    */
476   final public void setOnmousemove(String onmousemove)
477   {
478     setProperty(ONMOUSEMOVE_KEY, (onmousemove));
479   }
480 
481   /**
482    * Gets an onmouseout Javascript handler.
483    *
484    * @return  the new onmouseout value
485    */
486   final public String getOnmouseout()
487   {
488     return ComponentUtils.resolveString(getProperty(ONMOUSEOUT_KEY));
489   }
490 
491   /**
492    * Sets an onmouseout Javascript handler.
493    * 
494    * @param onmouseout  the new onmouseout value
495    */
496   final public void setOnmouseout(String onmouseout)
497   {
498     setProperty(ONMOUSEOUT_KEY, (onmouseout));
499   }
500 
501   /**
502    * Gets an onkeypress Javascript handler.
503    *
504    * @return  the new onkeypress value
505    */
506   final public String getOnkeypress()
507   {
508     return ComponentUtils.resolveString(getProperty(ONKEYPRESS_KEY));
509   }
510 
511   /**
512    * Sets an onkeypress Javascript handler.
513    * 
514    * @param onkeypress  the new onkeypress value
515    */
516   final public void setOnkeypress(String onkeypress)
517   {
518     setProperty(ONKEYPRESS_KEY, (onkeypress));
519   }
520 
521   /**
522    * Gets an onkeydown Javascript handler.
523    *
524    * @return  the new onkeydown value
525    */
526   final public String getOnkeydown()
527   {
528     return ComponentUtils.resolveString(getProperty(ONKEYDOWN_KEY));
529   }
530 
531   /**
532    * Sets an onkeydown Javascript handler.
533    * 
534    * @param onkeydown  the new onkeydown value
535    */
536   final public void setOnkeydown(String onkeydown)
537   {
538     setProperty(ONKEYDOWN_KEY, (onkeydown));
539   }
540 
541   /**
542    * Gets an onkeyup Javascript handler.
543    *
544    * @return  the new onkeyup value
545    */
546   final public String getOnkeyup()
547   {
548     return ComponentUtils.resolveString(getProperty(ONKEYUP_KEY));
549   }
550 
551   /**
552    * Sets an onkeyup Javascript handler.
553    * 
554    * @param onkeyup  the new onkeyup value
555    */
556   final public void setOnkeyup(String onkeyup)
557   {
558     setProperty(ONKEYUP_KEY, (onkeyup));
559   }
560 
561   /**
562    * Gets Indicates whether a minimum of one detail item must be
563    * disclosed at a time.  Use "false" (the default) to keep a minimum of one
564    * detail item disclosed at all times.  Use "true" to make it possible for
565    * all items to be collapsed.
566    *
567    * @return  the new discloseNone value
568    */
569   final public boolean isDiscloseNone()
570   {
571     return ComponentUtils.resolveBoolean(getProperty(DISCLOSE_NONE_KEY), false);
572   }
573 
574   /**
575    * Sets Indicates whether a minimum of one detail item must be
576    * disclosed at a time.  Use "false" (the default) to keep a minimum of one
577    * detail item disclosed at all times.  Use "true" to make it possible for
578    * all items to be collapsed.
579    * 
580    * @param discloseNone  the new discloseNone value
581    */
582   final public void setDiscloseNone(boolean discloseNone)
583   {
584     setProperty(DISCLOSE_NONE_KEY, discloseNone ? Boolean.TRUE : Boolean.FALSE);
585   }
586 
587   /**
588    * Gets Indicates whether more than one detail item may be
589    * disclosed at a time.  Use "false" (the default) to keep a maximum of
590    * one detail item disclosed at all times.  Use "true" to make it
591    * possible for multiple detail items to be disclosed.
592    *
593    * @return  the new discloseMany value
594    */
595   final public boolean isDiscloseMany()
596   {
597     return ComponentUtils.resolveBoolean(getProperty(DISCLOSE_MANY_KEY), false);
598   }
599 
600   /**
601    * Sets Indicates whether more than one detail item may be
602    * disclosed at a time.  Use "false" (the default) to keep a maximum of
603    * one detail item disclosed at all times.  Use "true" to make it
604    * possible for multiple detail items to be disclosed.
605    * 
606    * @param discloseMany  the new discloseMany value
607    */
608   final public void setDiscloseMany(boolean discloseMany)
609   {
610     setProperty(DISCLOSE_MANY_KEY, discloseMany ? Boolean.TRUE : Boolean.FALSE);
611   }
612 
613   @Override
614   public String getDefaultEventName()
615   {
616     return "click";
617   }
618 
619   @Override
620   public Collection<String> getEventNames()
621   {
622     return _EVENT_NAMES;
623   }
624 
625   @Override
626   public Map<String, List<ClientBehavior>> getClientBehaviors()
627   {
628     return super.getClientBehaviors();
629   }
630 
631   @Override
632   public void addClientBehavior(
633     String         eventName,
634     ClientBehavior behavior)
635   {
636     super.addClientBehavior(eventName, behavior);
637   }
638 
639   @Override
640   public String getFamily()
641   {
642     return COMPONENT_FAMILY;
643   }
644 
645   @Override
646   protected FacesBean.Type getBeanType()
647   {
648     return TYPE;
649   }
650 
651   /**
652    * Construct an instance of the CorePanelAccordion.
653    */
654   protected CorePanelAccordion(
655     String rendererType
656     )
657   {
658     super(rendererType);
659   }
660 
661   static
662   {
663     TYPE.lockAndRegister("org.apache.myfaces.trinidad.Panel","org.apache.myfaces.trinidad.Accordion");
664   }
665 }