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  
20  package org.apache.myfaces.tobago.renderkit.css;
21  
22  import org.apache.myfaces.tobago.component.Attributes;
23  import org.apache.myfaces.tobago.context.Markup;
24  import org.apache.myfaces.tobago.layout.AlignItems;
25  import org.apache.myfaces.tobago.layout.JustifyContent;
26  import org.apache.myfaces.tobago.layout.Margin;
27  import org.apache.myfaces.tobago.layout.MarginTokens;
28  import org.apache.myfaces.tobago.layout.Measure;
29  import org.apache.myfaces.tobago.layout.MeasureList;
30  import org.apache.myfaces.tobago.layout.SegmentJustify;
31  import org.apache.myfaces.tobago.layout.TextAlign;
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  
35  import javax.faces.application.FacesMessage;
36  import javax.faces.component.UIComponent;
37  import java.lang.invoke.MethodHandles;
38  import java.util.ArrayList;
39  import java.util.List;
40  import java.util.Map;
41  
42  /**
43   * CSS classes for the Bootstrap Library.
44   *
45   * @since 3.0.0
46   */
47  public enum BootstrapClass implements CssItem {
48  
49    ACTIVE("active"),
50    ALERT("alert"),
51    ALERT_DANGER("alert-danger"),
52    ALERT_WARNING("alert-warning"),
53    ALERT_INFO("alert-info"),
54    ALERT_DISMISSIBLE("alert-dismissible"),
55    ALIGN_ITEMS_BASELINE("align-items-baseline"),
56    ALIGN_ITEMS_CENTER("align-items-center"),
57    ALIGN_ITEMS_END("align-items-end"),
58    ALIGN_ITEMS_START("align-items-start"),
59    ALIGN_ITEMS_STRETCH("align-items-stretch"),
60    /**
61     * @deprecated since 5.0.0, please use {@link #POPOVER_ARROW} or {@link #TOOLTIP_ARROW}
62     */
63    @Deprecated
64    ARROW("arrow"),
65    BG_DANGER("bg-danger"),
66    BG_DARK("bg-dark"),
67    BG_INFO("bg-info"),
68    BG_LIGHT("bg-light"),
69    BG_PRIMARY("bg-primary"),
70    BG_SECONDARY("bg-secondary"),
71    BG_SUCCESS("bg-success"),
72    BG_WARNING("bg-warning"),
73    BADGE("badge"),
74    /**
75     * @deprecated since 5.0.0, please use {@link #BG_DANGER}
76     */
77    @Deprecated
78    BADGE_DANGER("bg-danger"),
79    /**
80     * @deprecated since 5.0.0, please use {@link #BG_DARK}
81     */
82    @Deprecated
83    BADGE_DARK("bg-dark"),
84    /**
85     * @deprecated since 5.0.0, please use {@link #BG_INFO}
86     */
87    @Deprecated
88    BADGE_INFO("bg-info"),
89    /**
90     * @deprecated since 5.0.0, please use {@link #BG_LIGHT}
91     */
92    @Deprecated
93    BADGE_LIGHT("bg-light"),
94    /**
95     * @deprecated since 5.0.0, please use {@link #ROUNDED_PILL}
96     */
97    @Deprecated
98    BADGE_PILL("rounded-pill"),
99    /**
100    * @deprecated since 5.0.0, please use {@link #BG_PRIMARY}
101    */
102   @Deprecated
103   BADGE_PRIMARY("bg-primary"),
104   /**
105    * @deprecated since 5.0.0, please use {@link #BG_SECONDARY}
106    */
107   @Deprecated
108   BADGE_SECONDARY("bg-secondary"),
109   /**
110    * @deprecated since 5.0.0, please use {@link #BG_SUCCESS}
111    */
112   @Deprecated
113   BADGE_SUCCESS("bg-success"),
114   /**
115    * @deprecated since 5.0.0, please use {@link #BG_WARNING}
116    */
117   @Deprecated
118   BADGE_WARNING("bg-warning"),
119   BORDER_DANGER("border-danger"),
120   BORDER_INFO("border-info"),
121   BORDER_WARNING("border-warning"),
122   BTN("btn"),
123   BTN_CLOSE("btn-close"),
124   BTN_DANGER("btn-danger"),
125   BTN_DARK("btn-dark"),
126   BTN_GROUP("btn-group"),
127   BTN_GROUP_VERTICAL("btn-group-vertical"),
128   BTN_INFO("btn-info"),
129   BTN_LIGHT("btn-light"),
130   BTN_LINK("btn-link"),
131   BTN_PRIMARY("btn-primary"),
132   BTN_OUTLINE_DANGER("btn-outline-danger"),
133   BTN_OUTLINE_DARK("btn-outline-dark"),
134   BTN_OUTLINE_INFO("btn-outline-info"),
135   BTN_OUTLINE_LIGHT("btn-outline-light"),
136   BTN_OUTLINE_PRIMARY("btn-outline-primary"),
137   BTN_OUTLINE_SECONDARY("btn-outline-secondary"),
138   BTN_OUTLINE_SUCCESS("btn-outline-success"),
139   BTN_OUTLINE_WARNING("btn-outline-warning"),
140   BTN_SECONDARY("btn-secondary"),
141   BTN_SUCCESS("btn-success"),
142   BTN_TOOLBAR("btn-toolbar"),
143   BTN_WARNING("btn-warning"),
144   CARD("card"),
145   CARD_BODY("card-body"),
146   CARD_HEADER("card-header"),
147   CARD_HEADER_TABS("card-header-tabs"),
148   CARD_TITLE("card-title"),
149   /**
150    * @deprecated since 5.0.0, please use {@link #BTN_CLOSE}
151    */
152   @Deprecated
153   CLOSE("btn-close"),
154   COLLAPSE("collapse"),
155   COL_FORM_LABEL("col-form-label"),
156   COL_LG("col-lg"),
157   COL_LG_1("col-lg-1"),
158   COL_LG_2("col-lg-2"),
159   COL_LG_3("col-lg-3"),
160   COL_LG_4("col-lg-4"),
161   COL_LG_5("col-lg-5"),
162   COL_LG_6("col-lg-6"),
163   COL_LG_7("col-lg-7"),
164   COL_LG_8("col-lg-8"),
165   COL_LG_9("col-lg-9"),
166   COL_LG_10("col-lg-10"),
167   COL_LG_11("col-lg-11"),
168   COL_LG_12("col-lg-12"),
169   COL_LG_AUTO("col-lg-auto"),
170   COL_MD("col-md"),
171   COL_MD_1("col-md-1"),
172   COL_MD_2("col-md-2"),
173   COL_MD_3("col-md-3"),
174   COL_MD_4("col-md-4"),
175   COL_MD_5("col-md-5"),
176   COL_MD_6("col-md-6"),
177   COL_MD_7("col-md-7"),
178   COL_MD_8("col-md-8"),
179   COL_MD_9("col-md-9"),
180   COL_MD_10("col-md-10"),
181   COL_MD_11("col-md-11"),
182   COL_MD_12("col-md-12"),
183   COL_MD_AUTO("col-md-auto"),
184   COL_SM("col-sm"),
185   COL_SM_1("col-sm-1"),
186   COL_SM_2("col-sm-2"),
187   COL_SM_3("col-sm-3"),
188   COL_SM_4("col-sm-4"),
189   COL_SM_5("col-sm-5"),
190   COL_SM_6("col-sm-6"),
191   COL_SM_7("col-sm-7"),
192   COL_SM_8("col-sm-8"),
193   COL_SM_9("col-sm-9"),
194   COL_SM_10("col-sm-10"),
195   COL_SM_11("col-sm-11"),
196   COL_SM_12("col-sm-12"),
197   COL_SM_AUTO("col-sm-auto"),
198   COL_XL("col-xl"),
199   COL_XL_1("col-xl-1"),
200   COL_XL_2("col-xl-2"),
201   COL_XL_3("col-xl-3"),
202   COL_XL_4("col-xl-4"),
203   COL_XL_5("col-xl-5"),
204   COL_XL_6("col-xl-6"),
205   COL_XL_7("col-xl-7"),
206   COL_XL_8("col-xl-8"),
207   COL_XL_9("col-xl-9"),
208   COL_XL_10("col-xl-10"),
209   COL_XL_11("col-xl-11"),
210   COL_XL_12("col-xl-12"),
211   COL_XL_AUTO("col-xl-auto"),
212   COL("col"),
213   COL_1("col-1"),
214   COL_2("col-2"),
215   COL_3("col-3"),
216   COL_4("col-4"),
217   COL_5("col-5"),
218   COL_6("col-6"),
219   COL_7("col-7"),
220   COL_8("col-8"),
221   COL_9("col-9"),
222   COL_10("col-10"),
223   COL_11("col-11"),
224   COL_12("col-12"),
225   COL_AUTO("col-auto"),
226   CONTAINER("container"),
227   CONTAINER_FLUID("container-fluid"),
228   /**
229    * @deprecated since 5.0.0, please use {@link #FORM_CHECK}
230    */
231   @Deprecated
232   CUSTOM_CHECKBOX("form-check"),
233   /**
234    * @deprecated since 5.0.0
235    */
236   @Deprecated
237   CUSTOM_CONTROL("custom-control"),
238   /**
239    * @deprecated since 5.0.0, please use {@link #FORM_CHECK_LABEL} or maybe any other?
240    */
241   @Deprecated
242   CUSTOM_CONTROL_LABEL("form-check-label"),
243   /**
244    * @deprecated since 5.0.0, please use {@link #FORM_CHECK_INLINE} or maybe any other?
245    */
246   @Deprecated
247   CUSTOM_CONTROL_INLINE("form-check-inline"),
248   /**
249    * @deprecated since 5.0.0, please use {@link #FORM_CHECK_INPUT} or maybe any other?
250    */
251   @Deprecated
252   CUSTOM_CONTROL_INPUT("form-check-input"),
253   /**
254    * @deprecated since 5.0.0, please use {@link #FORM_FILE}
255    */
256   @Deprecated
257   CUSTOM_FILE("custom-file"),
258   /**
259    * @deprecated since 5.0.0, please use {@link #FORM_FILE_INPUT}
260    */
261   @Deprecated
262   CUSTOM_FILE_INPUT("custom-file-input"),
263   /**
264    * @deprecated since 5.0.0, please use {@link #FORM_FILE_LABEL}
265    */
266   @Deprecated
267   CUSTOM_FILE_LABEL("custom-file-label"),
268   /**
269    * @deprecated since 5.0.0, please use {@link #FORM_CHECK}
270    */
271   @Deprecated
272   CUSTOM_RADIO("form-check"),
273   /**
274    * @deprecated since 5.0.0, please use {@link #FORM_SELECT}
275    */
276   @Deprecated
277   CUSTOM_SELECT("form-select"),
278   /**
279    * @deprecated since 5.0.0, please use {@link #FORM_SWITCH}
280    */
281   @Deprecated
282   CUSTOM_SWITCH("form-switch"),
283   D_FLEX("d-flex"),
284   D_INLINE("d-inline"),
285   D_NONE("d-none"),
286   D_SM_NONE("d-sm-none"),
287   DISABLED("disabled"),
288   DROPDOWN("dropdown"),
289   DROPDOWN_DIVIDER("dropdown-divider"),
290   DROPDOWN_ITEM("dropdown-item"),
291   DROPDOWN_MENU("dropdown-menu"),
292   DROPDOWN_MENU_RIGHT("dropdown-menu-right"),
293   DROPDOWN_TOGGLE("dropdown-toggle"),
294   FADE("fade"),
295   FIGURE("figure"),
296   FIGURE_CAPTION("figure-caption"),
297   FIGURE_IMG("figure-img"),
298   FIXED_BOTTOM("fixed-bottom"),
299   /**
300    * @deprecated since 5.0.0, please use {@link #STICKY_TOP}
301    */
302   @Deprecated
303   FIXED_TOP("fixed-top"),
304   FLEX_COLUMN("flex-column"),
305   FLEX_COLUMN_REVERSE("flex-column-reverse"),
306   FLEX_ROW("flex-row"),
307   FLEX_ROW_REVERSE("flex-row-reverse"),
308   FONT_ITALIC("font-italic"),
309   FONT_WEIGHT_BOLD("font-weight-bold"),
310   FONT_WEIGHT_LIGHT("font-weight-light"),
311   FORM_CHECK("form-check"),
312   FORM_CHECK_INLINE("form-check-inline"),
313   FORM_CHECK_INPUT("form-check-input"),
314   FORM_CHECK_LABEL("form-check-label"),
315   FORM_CONTROL("form-control"),
316   FORM_CONTROL_PLAINTEXT("form-control-plaintext"),
317   FORM_FILE("form-file"),
318   FORM_FILE_BUTTON("form-file-button"),
319   FORM_FILE_INPUT("form-file-input"),
320   FORM_FILE_LABEL("form-file-label"),
321   FORM_FILE_TEXT("form-file-text"),
322   /**
323    * @deprecated since 5.0.0, please use {@link #MB_3} or other
324    */
325   @Deprecated
326   FORM_GROUP("form-group"),
327   /**
328    * @deprecated since 5.0.0
329    */
330   @Deprecated
331   FORM_INLINE("form-inline"),
332   FORM_SELECT("form-select"),
333   FORM_SWITCH("form-switch"),
334   INPUT_GROUP("input-group"),
335   /**
336    * @deprecated since 5.0.0
337    */
338   @Deprecated
339   INPUT_GROUP_APPEND("input-group-append"),
340   /**
341    * @deprecated since 5.0.0
342    */
343   @Deprecated
344   INPUT_GROUP_PREPEND("input-group-prepend"),
345   INPUT_GROUP_TEXT("input-group-text"),
346   INVISIBLE("invisible"),
347   JUSTIFY_CONTENT_AROUND("justify-content-around"),
348   JUSTIFY_CONTENT_BETWEEN("justify-content-between"),
349   JUSTIFY_CONTENT_CENTER("justify-content-center"),
350   JUSTIFY_CONTENT_END("justify-content-end"),
351   JUSTIFY_CONTENT_START("justify-content-start"),
352   MB_0("mb-0"),
353   MB_1("mb-1"),
354   MB_2("mb-2"),
355   MB_3("mb-3"),
356   MB_4("mb-4"),
357   MB_5("mb-5"),
358   MB_AUTO("mb-auto"),
359   ML_0("ml-0"),
360   ML_1("ml-1"),
361   ML_2("ml-2"),
362   ML_3("ml-3"),
363   ML_4("ml-4"),
364   ML_5("ml-5"),
365   ML_AUTO("ml-auto"),
366   ML_LG_AUTO("ml-lg-auto"),
367   ML_MD_AUTO("ml-md-auto"),
368   ML_SM_AUTO("ml-sm-auto"),
369   ML_XL_AUTO("ml-xl-auto"),
370   MODAL("modal"),
371   MODAL_CONTENT("modal-content"),
372   MODAL_DIALOG("modal-dialog"),
373   MODAL_LG("modal-lg"),
374   MODAL_SM("modal-sm"),
375   MR_0("mr-0"),
376   MR_1("mr-1"),
377   MR_2("mr-2"),
378   MR_3("mr-3"),
379   MR_4("mr-4"),
380   MR_5("mr-5"),
381   MR_AUTO("mr-auto"),
382   MR_LG_AUTO("mr-lg-auto"),
383   MR_MD_AUTO("mr-md-auto"),
384   MR_SM_AUTO("mr-sm-auto"),
385   MR_XL_AUTO("mr-xl-auto"),
386   MT_0("mt-0"),
387   MT_1("mt-1"),
388   MT_2("mt-2"),
389   MT_3("mt-3"),
390   MT_4("mt-4"),
391   MT_5("mt-5"),
392   MT_AUTO("mt-auto"),
393   MY_LG_0("my-lg-0"),
394   MY_LG_1("my-lg-1"),
395   MY_LG_2("my-lg-2"),
396   MY_LG_3("my-lg-3"),
397   MY_LG_4("my-lg-4"),
398   MY_LG_5("my-lg-5"),
399   MX_AUTO("mx-auto"),
400   MX_LG_AUTO("mx-lg-auto"),
401   MX_MD_AUTO("mx-md-auto"),
402   MX_SM_AUTO("mx-sm-auto"),
403   MX_XL_AUTO("mx-xl-auto"),
404   NAV("nav"),
405   NAV_ITEM("nav-item"),
406   NAV_LINK("nav-link"),
407   NAV_TABS("nav-tabs"),
408   NAVBAR("navbar"),
409   NAVBAR_COLLAPSE("navbar-collapse"),
410   NAVBAR_BRAND("navbar-brand"),
411   NAVBAR_DARK("navbar-dark"),
412   NAVBAR_EXPAND("navbar-expand"),
413   NAVBAR_EXPAND_LG("navbar-expand-lg"),
414   NAVBAR_EXPAND_MD("navbar-expand-md"),
415   NAVBAR_EXPAND_SM("navbar-expand-sm"),
416   NAVBAR_EXPAND_XL("navbar-expand-xl"),
417   NAVBAR_LIGHT("navbar-light"),
418   NAVBAR_NAV("navbar-nav"),
419   NAVBAR_TOGGLER("navbar-toggler"),
420   NAVBAR_TOGGLER_ICON("navbar-toggler-icon"),
421   OFFSET_1("offset-1"),
422   OFFSET_2("offset-2"),
423   OFFSET_3("offset-3"),
424   OFFSET_4("offset-4"),
425   OFFSET_5("offset-5"),
426   OFFSET_6("offset-6"),
427   OFFSET_7("offset-7"),
428   OFFSET_8("offset-8"),
429   OFFSET_9("offset-9"),
430   OFFSET_10("offset-10"),
431   OFFSET_11("offset-11"),
432   OFFSET_LG_0("offset-lg-0"),
433   OFFSET_LG_1("offset-lg-1"),
434   OFFSET_LG_2("offset-lg-2"),
435   OFFSET_LG_3("offset-lg-3"),
436   OFFSET_LG_4("offset-lg-4"),
437   OFFSET_LG_5("offset-lg-5"),
438   OFFSET_LG_6("offset-lg-6"),
439   OFFSET_LG_7("offset-lg-7"),
440   OFFSET_LG_8("offset-lg-8"),
441   OFFSET_LG_9("offset-lg-9"),
442   OFFSET_LG_10("offset-lg-10"),
443   OFFSET_LG_11("offset-lg-11"),
444   OFFSET_MD_0("offset-md-0"),
445   OFFSET_MD_1("offset-md-1"),
446   OFFSET_MD_2("offset-md-2"),
447   OFFSET_MD_3("offset-md-3"),
448   OFFSET_MD_4("offset-md-4"),
449   OFFSET_MD_5("offset-md-5"),
450   OFFSET_MD_6("offset-md-6"),
451   OFFSET_MD_7("offset-md-7"),
452   OFFSET_MD_8("offset-md-8"),
453   OFFSET_MD_9("offset-md-9"),
454   OFFSET_MD_10("offset-md-10"),
455   OFFSET_MD_11("offset-md-11"),
456   OFFSET_SM_0("offset-sm-0"),
457   OFFSET_SM_1("offset-sm-1"),
458   OFFSET_SM_2("offset-sm-2"),
459   OFFSET_SM_3("offset-sm-3"),
460   OFFSET_SM_4("offset-sm-4"),
461   OFFSET_SM_5("offset-sm-5"),
462   OFFSET_SM_6("offset-sm-6"),
463   OFFSET_SM_7("offset-sm-7"),
464   OFFSET_SM_8("offset-sm-8"),
465   OFFSET_SM_9("offset-sm-9"),
466   OFFSET_SM_10("offset-sm-10"),
467   OFFSET_SM_11("offset-sm-11"),
468   OFFSET_XL_0("offset-xl-0"),
469   OFFSET_XL_1("offset-xl-1"),
470   OFFSET_XL_2("offset-xl-2"),
471   OFFSET_XL_3("offset-xl-3"),
472   OFFSET_XL_4("offset-xl-4"),
473   OFFSET_XL_5("offset-xl-5"),
474   OFFSET_XL_6("offset-xl-6"),
475   OFFSET_XL_7("offset-xl-7"),
476   OFFSET_XL_8("offset-xl-8"),
477   OFFSET_XL_9("offset-xl-9"),
478   OFFSET_XL_10("offset-xl-10"),
479   OFFSET_XL_11("offset-xl-11"),
480   PAGE_ITEM("page-item"),
481   PAGE_LINK("page-link"),
482   PAGINATION("pagination"),
483   POPOVER("popover"),
484   POPOVER_ARROW("popover-arrow"),
485   POPOVER_BODY("popover-body"),
486   POPOVER_HEADER("popover-header"),
487   PROGRESS("progress"),
488   PROGRESS_BAR("progress-bar"),
489   ROUNDED_PILL("rounded-pill"),
490   ROW("row"),
491   SHOW("show"),
492   /**
493    * @deprecated since 5.0.0, please use {@link #VISUALLY_HIDDEN}
494    */
495   @Deprecated
496   SR_ONLY("sr-only"),
497   STICKY_TOP("sticky-top"),
498   TEXT_DANGER("text-danger"),
499   TEXT_DARK("text-dark"),
500   TEXT_INFO("text-info"),
501   TEXT_LIGHT("text-light"),
502   TEXT_PRIMARY("text-primary"),
503   TEXT_SECONDARY("text-secondary"),
504   TEXT_SUCCESS("text-success"),
505   TEXT_WARNING("text-warning"),
506   TEXT_CENTER("text-center"),
507   /**
508    * @deprecated since 5.0.0, please use {@link org.apache.myfaces.tobago.renderkit.css.TobagoClass#TEXT__JUSTIFY}
509    */
510   @Deprecated
511   TEXT_JUSTIFY("tobago-text-justify"),
512   TEXT_LEFT("text-left"),
513   TEXT_RIGHT("text-right"),
514   TAB_CONTENT("tab-content"),
515   TAB_PANE("tab-pane"),
516   TABLE("table"),
517   TABLE_BORDERED("table-bordered"),
518   TABLE_DARK("table-dark"),
519   TABLE_HOVER("table-hover"),
520   TABLE_INFO("table-info"),
521   TABLE_SM("table-sm"),
522   TABLE_STRIPED("table-striped"),
523   TOOLTIP_ARROW("tooltip-arrow"),
524   VISUALLY_HIDDEN("visually-hidden");
525 
526   private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
527 
528   private static final int SEVERITY_ERROR = FacesMessage.SEVERITY_ERROR.getOrdinal();
529   private static final int SEVERITY_WARN = FacesMessage.SEVERITY_WARN.getOrdinal();
530   private static final int SEVERITY_INFO = FacesMessage.SEVERITY_INFO.getOrdinal();
531 
532   private final String name;
533 
534   BootstrapClass(final String name) {
535     this.name = name;
536   }
537 
538   @Override
539   public String getName() {
540     return name;
541   }
542 
543   public static CssItem alert(final FacesMessage.Severity severity) {
544 
545     // switch over severity.getOrdinal() doesn't work, because different implementations use different ordinals,
546     // see MYFACES-3768
547     // may be optimized with a cache...
548 
549     if (severity == null) {
550       return null;
551     } else if (severity.getOrdinal() >= SEVERITY_ERROR) {
552       return ALERT_DANGER;
553     } else if (severity.getOrdinal() >= SEVERITY_WARN) {
554       return ALERT_WARNING;
555     } else if (severity.getOrdinal() >= SEVERITY_INFO) {
556       return ALERT_INFO;
557     } else {
558       return null;
559     }
560   }
561 
562   public static CssItem borderColor(final FacesMessage.Severity severity) {
563     if (severity == null) {
564       return null;
565     }
566     return getSeverityCssItem(severity, BORDER_INFO, BORDER_WARNING, BORDER_DANGER);
567   }
568 
569   public static CssItem buttonColor(final FacesMessage.Severity severity) {
570     if (severity == null) {
571       return null;
572     }
573     return getSeverityCssItem(severity, BTN_INFO, BTN_WARNING, BTN_DANGER);
574   }
575 
576   private static CssItem getSeverityCssItem(FacesMessage.Severity severity,
577       BootstrapClass info, BootstrapClass warning, BootstrapClass error) {
578     if (severity.equals(FacesMessage.SEVERITY_INFO)) {
579       return info;
580     } else if (severity.equals(FacesMessage.SEVERITY_WARN)) {
581       return warning;
582     } else {
583       return error;
584     }
585   }
586 
587   public static CssItem segmentJustify(final SegmentJustify segmentJustify) {
588     switch (segmentJustify) {
589       case none:
590         return null;
591       case start:
592         return BootstrapClass.JUSTIFY_CONTENT_START;
593       case center:
594         return BootstrapClass.JUSTIFY_CONTENT_CENTER;
595       case end:
596         return BootstrapClass.JUSTIFY_CONTENT_END;
597       case around:
598         return BootstrapClass.JUSTIFY_CONTENT_AROUND;
599       case between:
600         return BootstrapClass.JUSTIFY_CONTENT_BETWEEN;
601       default:
602         LOG.warn("Not a bootstrap class defined for {}", segmentJustify);
603         return null;
604     }
605   }
606 
607   /**
608    * @since 4.0.0
609    */
610   public static CssItem textAlign(final TextAlign textAlign) {
611     switch (textAlign) {
612       case left:
613         return BootstrapClass.TEXT_LEFT;
614       case right:
615         return BootstrapClass.TEXT_RIGHT;
616       case justify:
617         return TobagoClass.TEXT__JUSTIFY;
618       case center:
619         return BootstrapClass.TEXT_CENTER;
620       default:
621         LOG.warn("Not a bootstrap class defined for {}", textAlign);
622         return BootstrapClass.TEXT_LEFT;
623     }
624   }
625 
626   public static CssItem textColor(final Markup markup) {
627     if (markup == null || markup.contains(Markup.NONE)) {
628       return null;
629     } else if (markup.contains(Markup.PRIMARY)) {
630       return BootstrapClass.TEXT_PRIMARY;
631     } else if (markup.contains(Markup.SECONDARY)) {
632       return BootstrapClass.TEXT_SECONDARY;
633     } else if (markup.contains(Markup.SUCCESS)) {
634       return BootstrapClass.TEXT_SUCCESS;
635     } else if (markup.contains(Markup.DANGER)) {
636       return BootstrapClass.TEXT_DANGER;
637     } else if (markup.contains(Markup.WARNING)) {
638       return BootstrapClass.TEXT_WARNING;
639     } else if (markup.contains(Markup.INFO)) {
640       return BootstrapClass.TEXT_INFO;
641     } else if (markup.contains(Markup.LIGHT)) {
642       return BootstrapClass.TEXT_LIGHT;
643     } else if (markup.contains(Markup.DARK)) {
644       return BootstrapClass.TEXT_DARK;
645     } else {
646       return null;
647     }
648   }
649 
650   public static CssItem fontStyle(final Markup markup) {
651     if (markup == null || markup.contains(Markup.NONE)) {
652       return null;
653     } else if (markup.contains(Markup.BOLD)) {
654       return BootstrapClass.FONT_WEIGHT_BOLD;
655     } else if (markup.contains(Markup.THIN)) {
656       return BootstrapClass.FONT_WEIGHT_LIGHT;
657     } else if (markup.contains(Markup.ITALIC)) {
658       return BootstrapClass.FONT_ITALIC;
659     } else {
660       return null;
661     }
662   }
663 
664   public static class Generator {
665 
666     private static final BootstrapClass[] OFFSET_EXTRA_SMALL = new BootstrapClass[]{
667         null, OFFSET_1, OFFSET_2, OFFSET_3, OFFSET_4, OFFSET_5,
668         OFFSET_6, OFFSET_7, OFFSET_8, OFFSET_9, OFFSET_10, OFFSET_11
669     };
670     private static final BootstrapClass[] OFFSET_SMALL = new BootstrapClass[]{
671         OFFSET_SM_0, OFFSET_SM_1, OFFSET_SM_2, OFFSET_SM_3, OFFSET_SM_4, OFFSET_SM_5,
672         OFFSET_SM_6, OFFSET_SM_7, OFFSET_SM_8, OFFSET_SM_9, OFFSET_SM_10, OFFSET_SM_11
673     };
674     private static final BootstrapClass[] OFFSET_MEDIUM = new BootstrapClass[]{
675         OFFSET_MD_0, OFFSET_MD_1, OFFSET_MD_2, OFFSET_MD_3, OFFSET_MD_4, OFFSET_MD_5,
676         OFFSET_MD_6, OFFSET_MD_7, OFFSET_MD_8, OFFSET_MD_9, OFFSET_MD_10, OFFSET_MD_11
677     };
678     private static final BootstrapClass[] OFFSET_LARGE = new BootstrapClass[]{
679         OFFSET_LG_0, OFFSET_LG_1, OFFSET_LG_2, OFFSET_LG_3, OFFSET_LG_4, OFFSET_LG_5,
680         OFFSET_LG_6, OFFSET_LG_7, OFFSET_LG_8, OFFSET_LG_9, OFFSET_LG_10, OFFSET_LG_11
681     };
682     private static final BootstrapClass[] OFFSET_EXTRA_LARGE = new BootstrapClass[]{
683         OFFSET_XL_0, OFFSET_XL_1, OFFSET_XL_2, OFFSET_XL_3, OFFSET_XL_4, OFFSET_XL_5,
684         OFFSET_XL_6, OFFSET_XL_7, OFFSET_XL_8, OFFSET_XL_9, OFFSET_XL_10, OFFSET_XL_11
685     };
686 
687     private final MeasureList extraSmall;
688     private final MeasureList small;
689     private final MeasureList medium;
690     private final MeasureList large;
691     private final MeasureList extraLarge;
692     private final MarginTokens marginExtraSmall;
693     private final MarginTokens marginSmall;
694     private final MarginTokens marginMedium;
695     private final MarginTokens marginLarge;
696     private final MarginTokens marginExtraLarge;
697 
698     private int index = 0;
699 
700     public Generator(
701         final MeasureList extraSmall, final MeasureList small, final MeasureList medium,
702         final MeasureList large, final MeasureList extraLarge,
703         final MarginTokens marginExtraSmall, final MarginTokens marginSmall, final MarginTokens marginMedium,
704         final MarginTokens marginLarge, final MarginTokens marginExtraLarge) {
705       if (extraSmall == null && small == null && medium == null && large == null && extraLarge == null) {
706         this.extraSmall = MeasureList.parse("*"); // TBD: is this needed? if yes, use Measure.FRACTION1
707       } else {
708         this.extraSmall = extraSmall;
709       }
710       this.small = small;
711       this.medium = medium;
712       this.large = large;
713       this.extraLarge = extraLarge;
714       this.marginExtraSmall = marginExtraSmall;
715       this.marginSmall = marginSmall;
716       this.marginMedium = marginMedium;
717       this.marginLarge = marginLarge;
718       this.marginExtraLarge = marginExtraLarge;
719     }
720 
721     public void reset() {
722       index = 0;
723     }
724 
725     public void next() {
726       index++;
727     }
728 
729     public BootstrapClass[] generate(final UIComponent child) {
730       final ArrayList<BootstrapClass> result = new ArrayList<>(10);
731       final Map<String, Object> attributes = child.getAttributes();
732       generate(result, extraSmall, attributes, Attributes.overwriteExtraSmall);
733       generate(result, small, attributes, Attributes.overwriteSmall);
734       generate(result, medium, attributes, Attributes.overwriteMedium);
735       generate(result, large, attributes, Attributes.overwriteLarge);
736       generate(result, extraLarge, attributes, Attributes.overwriteExtraLarge);
737 
738       generate(result, marginExtraSmall, attributes, Attributes.overwriteMarginExtraSmall);
739       generate(result, marginSmall, attributes, Attributes.overwriteMarginSmall);
740       generate(result, marginMedium, attributes, Attributes.overwriteMarginMedium);
741       generate(result, marginLarge, attributes, Attributes.overwriteMarginLarge);
742       generate(result, marginExtraLarge, attributes, Attributes.overwriteMarginExtraLarge);
743 
744       generateOffset(result, attributes.get(Attributes.offsetExtraSmall.name()), OFFSET_EXTRA_SMALL);
745       generateOffset(result, attributes.get(Attributes.offsetSmall.name()), OFFSET_SMALL);
746       generateOffset(result, attributes.get(Attributes.offsetMedium.name()), OFFSET_MEDIUM);
747       generateOffset(result, attributes.get(Attributes.offsetLarge.name()), OFFSET_LARGE);
748       generateOffset(result, attributes.get(Attributes.offsetExtraLarge.name()), OFFSET_EXTRA_LARGE);
749       return result.toArray(new BootstrapClass[0]);
750     }
751 
752     private void generate(
753         final List<BootstrapClass> result, final MeasureList tokens,
754         final Map<String, Object> attributes, final Attributes attribute) {
755       final Object overwrite = attributes.get(attribute.name());
756 
757       if (overwrite != null) {
758         final Measure measure = Measure.valueOf(overwrite.toString(), Measure.Unit.SEG);
759         final BootstrapClass bootstrapClass = valueOf(getSegmentMeasure(measure), attribute);
760         result.add(bootstrapClass);
761       } else if (tokens != null && tokens.getSize() > 0) {
762         final Measure measure = tokens.get(index % tokens.getSize());
763         final BootstrapClass bootstrapClass = valueOf(getSegmentMeasure(measure), attribute);
764         result.add(bootstrapClass);
765       }
766     }
767 
768     private Measure getSegmentMeasure(final Measure measure) {
769       if (measure != null && Measure.Unit.SEG.equals(measure.getUnit())) {
770         final int number = (int) measure.getValue();
771         if (number < 1) {
772           LOG.warn("Segment values must been between 1 and 12. Use '1' instead of '{}'.", number);
773           return new Measure(1, Measure.Unit.SEG);
774         } else if (number > 12) {
775           LOG.warn("Segment values must been between 1 and 12. Use '12' instead of '{}'.", number);
776           return new Measure(12, Measure.Unit.SEG);
777         }
778       }
779       return measure;
780     }
781 
782     private void generate(final List<BootstrapClass> result, final MarginTokens margins,
783         final Map<String, Object> attributes, final Attributes attribute) {
784       final Object overwrite = attributes.get(attribute.name());
785 
786       if (overwrite != null) {
787         final Margin margin = MarginTokens.parseToken((String) overwrite);
788         final BootstrapClass bootstrapClass = valueOf(margin, attribute);
789         result.add(bootstrapClass);
790       } else if (margins != null && margins.getSize() > 0) {
791         final Margin margin = margins.get(index % margins.getSize());
792         final BootstrapClass bootstrapClass = valueOf(margin, attribute);
793         result.add(bootstrapClass);
794       }
795     }
796 
797     private void generateOffset(final List<BootstrapClass> result, final Object offset, final BootstrapClass[] values) {
798       if (offset != null) {
799         int offsetIndex = Integer.parseInt((String) offset);
800         if (offsetIndex >= 0) {
801           offsetIndex = Math.min(offsetIndex, 11);
802           result.add(values[offsetIndex]);
803         }
804       }
805     }
806   }
807 
808   public static BootstrapClass valueOf(final Measure measure, final Attributes attributes) {
809     final String size = getSizeSuffix(attributes);
810 
811     if (measure != null) {
812       if (measure.getUnit() == Measure.Unit.FR) {
813         return valueOf("COL" + size);
814       } else if (measure.getUnit() == Measure.Unit.AUTO) {
815         return valueOf("COL" + size + "_AUTO");
816       } else if (measure.getUnit() == Measure.Unit.SEG) {
817         final float value = measure.getValue();
818         return valueOf(
819             "COL" + size + "_" + (value == (long) value ? Long.toString((long) value) : Float.toString(value)));
820       }
821     }
822     return null;
823   }
824 
825   public static BootstrapClass valueOf(final Margin margin, final Attributes attribute) {
826     final String size = getSizeSuffix(attribute);
827 
828     switch (margin) {
829       case left:
830         return valueOf("ML" + size + "_AUTO");
831       case right:
832         return valueOf("MR" + size + "_AUTO");
833       case both:
834         return valueOf("MX" + size + "_AUTO");
835       default:
836         return null;
837     }
838   }
839 
840   private static String getSizeSuffix(final Attributes attribute) {
841     switch (attribute) {
842       case extraLarge:
843       case marginExtraLarge:
844       case overwriteExtraLarge:
845       case overwriteMarginExtraLarge:
846         return "_XL";
847       case large:
848       case marginLarge:
849       case overwriteLarge:
850       case overwriteMarginLarge:
851         return "_LG";
852       case medium:
853       case marginMedium:
854       case overwriteMedium:
855       case overwriteMarginMedium:
856         return "_MD";
857       case small:
858       case marginSmall:
859       case overwriteSmall:
860       case overwriteMarginSmall:
861         return "_SM";
862       case extraSmall:
863       case marginExtraSmall:
864       case overwriteExtraSmall:
865       case overwriteMarginExtraSmall:
866       default:
867         return "";
868     }
869   }
870 
871   public static CssItem valueOf(final AlignItems alignItems) {
872     if (alignItems == null) {
873       return null;
874     } else {
875       switch (alignItems) {
876         case baseline:
877           return ALIGN_ITEMS_BASELINE;
878         case center:
879           return ALIGN_ITEMS_CENTER;
880         case flexEnd:
881           return ALIGN_ITEMS_END;
882         case flexStart:
883           return ALIGN_ITEMS_START;
884         case stretch:
885           return ALIGN_ITEMS_STRETCH;
886         default:
887           LOG.warn("Undefined alignItems: '{}'.", alignItems);
888           return null;
889       }
890     }
891   }
892 
893   public static CssItem valueOf(final JustifyContent justifyContent) {
894     if (justifyContent == null) {
895       return null;
896     } else {
897       switch (justifyContent) {
898         case center:
899           return JUSTIFY_CONTENT_CENTER;
900         case flexEnd:
901           return JUSTIFY_CONTENT_END;
902         case flexStart:
903           return JUSTIFY_CONTENT_START;
904         case spaceBetween:
905           return JUSTIFY_CONTENT_BETWEEN;
906         case spaceAround:
907           return JUSTIFY_CONTENT_AROUND;
908         default:
909           LOG.warn("Undefined justifyContent: '{}'.", justifyContent);
910           return null;
911       }
912     }
913   }
914 
915 }