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.html;
21  
22  import org.apache.commons.collections.set.ListOrderedSet;
23  import org.apache.commons.lang.StringUtils;
24  import org.apache.myfaces.tobago.component.Attributes;
25  import org.apache.myfaces.tobago.component.SupportsMarkup;
26  import org.apache.myfaces.tobago.context.ClientProperties;
27  import org.apache.myfaces.tobago.context.Markup;
28  import org.apache.myfaces.tobago.context.Theme;
29  import org.apache.myfaces.tobago.internal.util.Deprecation;
30  import org.apache.myfaces.tobago.util.ComponentUtils;
31  import org.slf4j.Logger;
32  import org.slf4j.LoggerFactory;
33  
34  import javax.faces.component.UIComponent;
35  import javax.faces.component.UIInput;
36  import javax.faces.context.FacesContext;
37  import java.io.Serializable;
38  import java.util.Iterator;
39  import java.util.Locale;
40  import java.util.Map;
41  
42  /**
43   * @deprecated since Tobago 1.5.0. Please use {@link org.apache.myfaces.tobago.renderkit.css.Classes}.
44   */
45  @Deprecated
46  public class StyleClasses implements Serializable {
47  
48    private static final long serialVersionUID = 3738052927067803517L;
49  
50    private static final Logger LOG = LoggerFactory.getLogger(StyleClasses.class);
51  
52    public static final char SEPARATOR = '-';
53    public static final String PREFIX = "tobago" + SEPARATOR;
54    public static final String MARKUP = SEPARATOR + "markup" + SEPARATOR;
55  
56    private ListOrderedSet classes;
57  
58    public StyleClasses() {
59      classes = new ListOrderedSet();
60    }
61  
62    /**
63     * Creates a StyleClasses element and adds one entry for a sub-component with the name of the renderer.
64     * E. g.: UITreeNode + "icon" -> tobago-treeNode-icon
65     */
66    public StyleClasses(final UIComponent component, final String sub) {
67      this();
68      addClass(StringUtils.uncapitalize(component.getRendererType()), sub);
69    }
70  
71    private StyleClasses(final StyleClasses base) {
72      this();
73      classes.addAll(base.classes);
74    }
75  
76    public static StyleClasses ensureStyleClasses(final UIComponent component) {
77      final Map attributes = component.getAttributes();
78      StyleClasses classes = (StyleClasses) attributes.get(Attributes.STYLE_CLASS);
79      if (classes == null) {
80        classes = new StyleClasses();
81        attributes.put(Attributes.STYLE_CLASS, classes);
82      }
83      return classes;
84    }
85  
86    public static StyleClasses ensureStyleClassesCopy(final UIComponent component) {
87      return new StyleClasses(ensureStyleClasses(component));
88    }
89  
90    /**
91     * @deprecated since Tobago 1.5.0. Please use {@link org.apache.myfaces.tobago.renderkit.css.Classes}.
92     */
93    @Deprecated
94    public void addFullQualifiedClass(final String clazz) {
95      classes.add(clazz);
96    }
97    /**
98     * @deprecated since Tobago 1.5.0. Please use {@link org.apache.myfaces.tobago.renderkit.css.Classes}.
99     */
100   @Deprecated
101   public void removeFullQualifiedClass(final String clazz) {
102     classes.remove(clazz);
103   }
104 
105   public void addClass(final String renderer, final String sub) {
106     classes.add(nameOfClass(renderer, sub));
107   }
108 
109   public void removeClass(final String renderer, final String sub) {
110     classes.remove(nameOfClass(renderer, sub));
111   }
112 
113   public boolean isEmpty() {
114     return classes.isEmpty();
115   }
116 
117   private String nameOfClass(final String renderer, final String sub) {
118     final StringBuilder builder = new StringBuilder(PREFIX);
119     builder.append(renderer);
120     builder.append(SEPARATOR);
121     builder.append(sub);
122     return builder.toString();
123   }
124 
125   public void addMarkupClass(final String renderer, final String markup) {
126     addMarkupClass(renderer, null, markup);
127   }
128 
129   public void removeMarkupClass(final String renderer, final String markup) {
130     removeMarkupClass(renderer, null, markup);
131   }
132 
133   public void addMarkupClass(final String renderer, final String sub, final String markup) {
134     classes.add(nameOfMarkupClass(renderer, sub, markup));
135   }
136 
137   public void removeMarkupClass(final String renderer, final String sub, final String markup) {
138     classes.remove(nameOfMarkupClass(renderer, sub, markup));
139   }
140 
141   private String nameOfMarkupClass(final String renderer, final String sub, final String markup) {
142     final StringBuilder builder = new StringBuilder(PREFIX);
143     builder.append(renderer);
144     if (sub != null) {
145       builder.append(SEPARATOR);
146       builder.append(sub);
147     }
148     builder.append(MARKUP);
149     builder.append(markup);
150     return builder.toString();
151   }
152 
153   public void addMarkupClass(final UIComponent component, final String rendererName) {
154     if (component instanceof SupportsMarkup) {
155       addMarkupClass((SupportsMarkup) component, rendererName, null);
156     }
157   }
158 
159   public void addMarkupClass(final SupportsMarkup supportsMarkup, final String rendererName, final String sub) {
160     final Markup m = supportsMarkup.getCurrentMarkup();
161     if (m != null) {
162       for (final String markup : m) {
163         final Theme theme = ClientProperties.getInstance(FacesContext.getCurrentInstance()).getTheme();
164         if (theme.getRenderersConfig().isMarkupSupported(rendererName, markup)) {
165           addMarkupClass(rendererName, sub, markup);
166         } else if ("none".equals(markup)) {
167           Deprecation.LOG.warn("Markup 'none' is deprecated, please use a NULL pointer instead.");
168         } else {
169           LOG.warn("Unknown markup='" + markup + "'");
170         }
171       }
172     }
173   }
174 
175   public void addAspectClass(final String renderer, final Aspect aspect) {
176     classes.add(nameOfAspectClass(renderer, aspect));
177   }
178 
179   public void removeAspectClass(final String renderer, final Aspect aspect) {
180     classes.remove(nameOfAspectClass(renderer, aspect));
181   }
182 
183   private String nameOfAspectClass(final String renderer, final Aspect aspect) {
184     final StringBuilder builder = new StringBuilder(PREFIX);
185     builder.append(renderer);
186     builder.append(aspect);
187     return builder.toString();
188   }
189 
190   public void addAspectClass(final String renderer, final String sub, final Aspect aspect) {
191     classes.add(nameOfAspectClass(renderer, sub, aspect));
192   }
193 
194   public void removeAspectClass(final String renderer, final String sub, final Aspect aspect) {
195     classes.remove(nameOfAspectClass(renderer, sub, aspect));
196   }
197 
198   private String nameOfAspectClass(final String renderer, final String sub, final Aspect aspect) {
199     final StringBuilder builder = new StringBuilder(PREFIX);
200     builder.append(renderer);
201     builder.append(SEPARATOR);
202     builder.append(sub);
203     builder.append(aspect);
204     return builder.toString();
205   }
206 
207   public void addClasses(final StyleClasses styleClasses) {
208     for (final String clazz : (Iterable<String>) styleClasses.classes) {
209       classes.add(clazz);
210     }
211   }
212 
213   public void removeClass(final String clazz) {
214     classes.remove(clazz);
215   }
216 
217   public void removeTobagoClasses(final String rendererName) {
218     for (final Iterator i = classes.iterator(); i.hasNext();) {
219       final String clazz = (String) i.next();
220       if (clazz.startsWith(PREFIX + rendererName)) {
221         i.remove();
222       }
223     }
224   }
225 
226   public void updateClassAttributeAndMarkup(final UIComponent component, final String rendererName) {
227     updateClassAttribute(component, rendererName);
228     addMarkupClass(component, rendererName);
229   }
230 
231   public void updateClassAttribute(final UIComponent component, final String rendererName) {
232     // first remove old tobago-<rendererName>-<type> classes from class-attribute
233     removeTobagoClasses(rendererName);
234 
235     addAspectClass(rendererName, Aspect.DEFAULT);
236     if (ComponentUtils.getBooleanAttribute(component, Attributes.DISABLED)) {
237       addAspectClass(rendererName, Aspect.DISABLED);
238     }
239     if (ComponentUtils.getBooleanAttribute(component, Attributes.READONLY)) {
240       addAspectClass(rendererName, Aspect.READONLY);
241     }
242     if (ComponentUtils.getBooleanAttribute(component, Attributes.INLINE)) {
243       addAspectClass(rendererName, Aspect.INLINE);
244     }
245     if (component instanceof UIInput) {
246       final UIInput input = (UIInput) component;
247       if (ComponentUtils.isError(input)) {
248         addAspectClass(rendererName, Aspect.ERROR);
249       }
250       if (input.isRequired()) {
251         addAspectClass(rendererName, Aspect.REQUIRED);
252       }
253     }
254   }
255 
256   @Override
257   public String toString() {
258     if (classes.isEmpty()) {
259       return null;
260     }
261     final StringBuilder buffer = new StringBuilder(16 * classes.size());
262     for (final Iterator i = classes.iterator(); i.hasNext();) {
263       final String clazz = (String) i.next();
264       buffer.append(clazz);
265       if (i.hasNext()) {
266         buffer.append(' ');
267       }
268     }
269     return buffer.toString();
270   }
271 
272   /**
273    * @deprecated since Tobago 1.5.0. Please use {@link org.apache.myfaces.tobago.context.Markup}.
274    */
275   @Deprecated
276   public enum Aspect {
277 
278     DEFAULT,
279     DISABLED,
280     READONLY,
281     INLINE,
282     ERROR,
283     REQUIRED;
284 
285     private String aspect;
286 
287     Aspect() {
288       aspect = name().equals("DEFAULT") ? "" : '-' + name().toLowerCase(Locale.ENGLISH);
289     }
290 
291     @Override
292     public String toString() {
293       return aspect;
294     }
295   }
296 }