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  package org.apache.myfaces.trinidad.style;
20  
21  import java.util.Collections;
22  import java.util.HashSet;
23  import java.util.Map;
24  import java.util.Set;
25  
26  /**
27   * Styles is a class that contains information about CSS Selectors and their
28   * corresponding Style object (i.e., the css properties) for the css selectors  
29   * that are written to the generated css file. The methods in this class
30   * are useful if you need to know in the renderer code what css properties
31   * a particular selector has.
32   */
33  public abstract class Styles
34  {
35  
36    /**
37     * Returns a Map containing the Selector Object as the key and the Style 
38     * Object as the value. 
39     * The Style object contains all the css property names/values.
40     * This Map can then be used to get all the selector keys, or to get the 
41     * Style Object for a Selector, or to get all the selectors that 
42     * match some criteria, like they contain a certain simple selector.
43     * 
44     * @return unmodifiableMap of the resolved Selector -> Style map.
45     */
46    public abstract Map<Selector, Style> getSelectorStyleMap();
47    
48    /**
49     * Returns the Selector in String form, converted to a format that
50     * is suitable to be written to the client (e.g., a css-2 format that can be
51     * read by a browser)
52     * @param selector Selector
53     * @return String the Selector in a String form that is suitable to be
54     * written to the client.
55     */
56    public abstract String getNativeSelectorString(Selector selector);
57    
58  
59    /**
60     * Given a simple selector (as opposed to a complex selector), 
61     * this method will return a Set of the Selectors that
62     * contain the simple selector. It calls getSelectorStyleMap() and then
63     * looks through each Selector to see if the simple selector is contained
64     * within it. If so, it puts it in a Set.
65     * The recommended usage is to call this for simple selectors, like
66     * "af|inputText" or "af|treeTable" and not selectors like 
67     * "af|inputText::content".
68     * @param simpleSelector
69     * @return an unmodfiable Set&lt;Selector> of all the complete selectors  
70     * that contain the simple selector.
71     */
72    public Set<Selector> getSelectorsForSimpleSelector(String simpleSelector)
73    {
74      Map<Selector, Style> selectorStyleMap = getSelectorStyleMap();
75      Set<Selector> set = null;
76      
77      // loop through each entry and find all simple selectors
78      for (Map.Entry<Selector, Style> entry : selectorStyleMap.entrySet())
79      {
80        Selector completeSelector = entry.getKey();
81        String completeSelectorString = completeSelector.toString();
82        int index = completeSelectorString.indexOf(simpleSelector);
83        boolean beforeSelectorOk = false;
84        boolean afterSelectorOk = false;
85        if (index > -1)
86        {
87          // found the simpleSelector within the complex selector
88          // double check that it is the simpleSelector by looking at the characters before
89          // and after. e.g., af|foobar does not contain the simple selector af|foo, whereas
90          // af|foo.bar or af|foo bar or af|foo:bar does.
91          if (index == 0)
92          {
93            beforeSelectorOk = true;
94          }
95          else
96          {
97            char c = completeSelectorString.charAt(index-1);
98            if (Character.isWhitespace(c) || c == '.')
99            {
100             beforeSelectorOk = true;
101           }
102         }
103         if (beforeSelectorOk)
104         {
105           // now check after the string.
106           int endIndex = index + simpleSelector.length();
107           if (endIndex < completeSelectorString.length())
108           {
109             char c = completeSelectorString.charAt(endIndex);
110             if (Character.isWhitespace(c) || c == '.' || c == ':')
111               afterSelectorOk = true;  
112           }
113           else
114             afterSelectorOk = true;
115         }
116         if (beforeSelectorOk && afterSelectorOk)
117         {
118           if (set == null)
119             set = new HashSet<Selector>(); 
120           set.add(completeSelector); 
121         }
122       }
123         
124     }
125     if (set == null)
126       return Collections.emptySet();
127     else
128       return Collections.unmodifiableSet(set);
129     
130   }
131   
132 }