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.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  
25  import javax.el.ELContext;
26  import javax.el.ValueExpression;
27  import javax.faces.context.FacesContext;
28  import java.lang.invoke.MethodHandles;
29  import java.util.StringTokenizer;
30  import java.util.regex.Matcher;
31  import java.util.regex.Pattern;
32  
33  /**
34   * Since Tobago 3.0.0
35   */
36  public class CustomClass implements CssItem {
37  
38    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
39  
40    private static final Pattern CSS_CLASS_PATTERN = Pattern.compile("[\\w-]+");
41  
42    private String name;
43    private ValueExpression valueExpression;
44  
45    public CustomClass(final String name) {
46      this.name = name;
47    }
48  
49    public CustomClass(final ValueExpression valueExpression) {
50      this.valueExpression = valueExpression;
51    }
52  
53    @Override
54    public String getName() {
55      final String string;
56      if (name != null) {
57        string = name;
58      } else if (valueExpression != null) {
59        final FacesContext facesContext = FacesContext.getCurrentInstance();
60        final ELContext elContext = facesContext.getELContext();
61        final Object valueExpressionValue = valueExpression.getValue(elContext);
62        if (valueExpressionValue != null) {
63          string = valueExpressionValue.toString();
64        } else {
65          return "";
66        }
67      } else {
68        return "";
69      }
70  
71      final StringTokenizer tokenizer = new StringTokenizer(string, " ");
72      final StringBuilder result = new StringBuilder();
73      boolean first = true;
74      while (tokenizer.hasMoreTokens()) {
75        final String token = tokenizer.nextToken();
76        final Matcher matcher = CSS_CLASS_PATTERN.matcher(token);
77        if (matcher.matches()) {
78          if (!first) {
79            result.append(' ');
80          }
81          result.append(token);
82          first = false;
83        } else {
84          LOG.error("Invalid CSS class name: '{}' which is part of '{}'", token, string);
85        }
86      }
87      return result.toString();
88    }
89  
90    /**
91     * @deprecated since 4.0.0
92     */
93    @Deprecated
94    public static CustomClass valueOf(final String text) {
95      return new CustomClass(text);
96    }
97  }