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.layout;
21  
22  import org.apache.myfaces.tobago.internal.util.NumberUtils;
23  import org.slf4j.Logger;
24  import org.slf4j.LoggerFactory;
25  
26  import java.util.ArrayList;
27  import java.util.Iterator;
28  import java.util.List;
29  import java.util.StringTokenizer;
30  
31  public final class LayoutTokens implements Iterable<LayoutToken> {
32  
33    private static final Logger LOG = LoggerFactory.getLogger(LayoutTokens.class);
34  
35    private List<LayoutToken> tokens = new ArrayList<LayoutToken>();
36  
37    public LayoutTokens() {
38    }
39  
40    public int getSize() {
41      return tokens.size();
42    }
43  
44    public void set(final int index, final LayoutToken token) {
45      tokens.set(index, token);
46    }
47  
48    public boolean isEmpty() {
49      return getSize() == 0;
50    }
51  
52    public LayoutToken get(final int index) {
53      return tokens.get(index);
54    }
55  
56    public void shrinkSizeTo(final int size) {
57      for (int i = getSize() - 1; i >= size; i--) {
58        tokens.remove(i);
59      }
60    }
61  
62    public void ensureSize(final int size, final LayoutToken token) {
63      for (int index = getSize(); index < size; index++) {
64        addToken(token);
65      }
66    }
67  
68    public void addToken(final LayoutToken token) {
69      tokens.add(token);
70    }
71  
72    public List<LayoutToken> getTokens() {
73      return tokens;
74    }
75  
76    public Iterator<LayoutToken> iterator() {
77      return tokens.iterator();
78    }
79  
80    public static LayoutTokens parse(final String[] tokens) {
81      final LayoutTokens layoutTokens = new LayoutTokens();
82      for (final String token : tokens) {
83        parseToken(token, layoutTokens);
84      }
85      return layoutTokens;
86    }
87  
88    public static LayoutTokens parse(final String tokens) {
89      return parse(tokens, null);
90    }
91  
92    public static LayoutTokens parse(final String tokens, final LayoutToken defaultToken) {
93      final LayoutTokens layoutTokens = new LayoutTokens();
94      if (tokens == null) {
95        layoutTokens.addToken(defaultToken);
96        return layoutTokens;
97      }
98      final StringTokenizer tokenizer = new StringTokenizer(tokens, ";");
99  
100     while (tokenizer.hasMoreTokens()) {
101       final String token = tokenizer.nextToken().trim();
102       parseToken(token, layoutTokens);
103     }
104     return layoutTokens;
105   }
106 
107   private static void parseToken(final String token, final LayoutTokens layoutTokens) {
108     final LayoutToken layoutToken = parseToken(token);
109     if (layoutToken != null) {
110       layoutTokens.addToken(layoutToken);
111     }
112   }
113 
114   public static LayoutToken parseToken(final String token) {
115     try {
116       if ("*".equals(token)) {
117         return RelativeLayoutToken.DEFAULT_INSTANCE;
118       } else if (token == null) {
119         LOG.error("Empty layout token! Using 'auto' instead.");
120         return AutoLayoutToken.INSTANCE;
121       } else if ("fixed".equals(token) || "auto".equals(token)) {
122         return AutoLayoutToken.INSTANCE;
123       } else if ("minimum".equals(token)) {
124         return new MinimumLayoutToken();
125       } else if (isPixelToken(token)) {
126         return new PixelLayoutToken(Integer.parseInt(removeSuffix(token, PixelLayoutToken.SUFFIX)));
127       } else if (isPercentToken(token)) {
128         return new PercentLayoutToken(Integer.parseInt(removeSuffix(token, PercentLayoutToken.SUFFIX)));
129       } else if (isRelativeToken(token)) {
130         return new RelativeLayoutToken(Integer.parseInt(removeSuffix(token, RelativeLayoutToken.SUFFIX)));
131       } else {
132         LOG.error("Unknown layout token '" + token + "'! Using 'auto' instead.");
133         return AutoLayoutToken.INSTANCE;
134       }
135     } catch (final NumberFormatException e) {
136       LOG.error("Error parsing layout token '" + token + "'! Using 'auto' instead.");
137       return AutoLayoutToken.INSTANCE;
138     }
139   }
140 
141   static boolean isPixelToken(final String token) {
142     return isNumberAndSuffix(token, PixelLayoutToken.SUFFIX);
143   }
144 
145   static boolean isPercentToken(final String token) {
146     return isNumberAndSuffix(token, PercentLayoutToken.SUFFIX);
147   }
148 
149   static boolean isRelativeToken(final String token) {
150     return isNumberAndSuffix(token, RelativeLayoutToken.SUFFIX);
151   }
152 
153   static boolean isNumberAndSuffix(final String token, final String suffix) {
154     return token.endsWith(suffix) && NumberUtils.isDigits(removeSuffix(token, suffix));
155   }
156 
157   private static String removeSuffix(final String token, final String suffix) {
158     return token.substring(0, token.length() - suffix.length());
159   }
160 
161   public String toString() {
162     final StringBuilder str = new StringBuilder();
163     for (final LayoutToken token : tokens) {
164       str.append(token);
165       str.append(";");
166     }
167     return str.toString();
168   }
169 
170 }