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 addToken(final LayoutToken token) {
57      tokens.add(token);
58    }
59  
60    public List<LayoutToken> getTokens() {
61      return tokens;
62    }
63  
64    @Override
65    public Iterator<LayoutToken> iterator() {
66      return tokens.iterator();
67    }
68  
69    public static LayoutTokens parse(final String[] tokens) {
70      final LayoutTokens layoutTokens = new LayoutTokens();
71      for (final String token : tokens) {
72        parseToken(token, layoutTokens);
73      }
74      return layoutTokens;
75    }
76  
77    public static LayoutTokens parse(final String tokens) {
78      return parse(tokens, null);
79    }
80  
81    public static LayoutTokens parse(final String tokens, final LayoutToken defaultToken) {
82      final LayoutTokens layoutTokens = new LayoutTokens();
83      if (tokens == null) {
84        layoutTokens.addToken(defaultToken);
85        return layoutTokens;
86      }
87      final StringTokenizer tokenizer = new StringTokenizer(tokens, ";");
88  
89      while (tokenizer.hasMoreTokens()) {
90        final String token = tokenizer.nextToken().trim();
91        parseToken(token, layoutTokens);
92      }
93      return layoutTokens;
94    }
95  
96    private static void parseToken(final String token, final LayoutTokens layoutTokens) {
97      final LayoutToken layoutToken = parseToken(token);
98      if (layoutToken != null) {
99        layoutTokens.addToken(layoutToken);
100     }
101   }
102 
103   public static LayoutToken parseToken(final String token) {
104     try {
105       if ("*".equals(token)) {
106         return RelativeLayoutToken.DEFAULT_INSTANCE;
107       } else if (token == null) {
108         LOG.error("Empty layout token! Using 'auto' instead.");
109         return AutoLayoutToken.INSTANCE;
110       } else if ("fixed".equals(token) || "auto".equals(token)) {
111         return AutoLayoutToken.INSTANCE;
112       } else if ("minimum".equals(token)) {
113         return new MinimumLayoutToken();
114       } else if (isPercentToken(token)) {
115         return new PercentLayoutToken(Integer.parseInt(removeSuffix(token, PercentLayoutToken.SUFFIX)));
116       } else if (isRelativeToken(token)) {
117         return new RelativeLayoutToken(Integer.parseInt(removeSuffix(token, RelativeLayoutToken.SUFFIX)));
118       } else {
119         return new MeasureLayoutToken(token);
120       }
121     } catch (final NumberFormatException e) {
122       LOG.error("Error parsing layout token '" + token + "'! Using 'auto' instead.");
123       return AutoLayoutToken.INSTANCE;
124     }
125   }
126 
127   static boolean isPercentToken(final String token) {
128     return isNumberAndSuffix(token, PercentLayoutToken.SUFFIX);
129   }
130 
131   static boolean isRelativeToken(final String token) {
132     return isNumberAndSuffix(token, RelativeLayoutToken.SUFFIX);
133   }
134 
135   static boolean isNumberAndSuffix(final String token, final String suffix) {
136     return token.endsWith(suffix) && NumberUtils.isDigits(removeSuffix(token, suffix));
137   }
138 
139   private static String removeSuffix(final String token, final String suffix) {
140     return token.substring(0, token.length() - suffix.length());
141   }
142 
143   public String toString() {
144     final StringBuilder str = new StringBuilder();
145     for (final LayoutToken token : tokens) {
146       str.append(token);
147       str.append(";");
148     }
149     return str.toString();
150   }
151 
152 }