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 (isRelativeToken(token)) {
115         return new RelativeLayoutToken(Integer.parseInt(removeSuffix(token, RelativeLayoutToken.SUFFIX)));
116       } else {
117         return new MeasureLayoutToken(token);
118       }
119     } catch (final NumberFormatException e) {
120       LOG.error("Error parsing layout token '" + token + "'! Using 'auto' instead.");
121       return AutoLayoutToken.INSTANCE;
122     }
123   }
124 
125   static boolean isRelativeToken(final String token) {
126     return isNumberAndSuffix(token, RelativeLayoutToken.SUFFIX);
127   }
128 
129   static boolean isNumberAndSuffix(final String token, final String suffix) {
130     return token.endsWith(suffix) && NumberUtils.isDigits(removeSuffix(token, suffix));
131   }
132 
133   private static String removeSuffix(final String token, final String suffix) {
134     return token.substring(0, token.length() - suffix.length());
135   }
136 
137   public String toString() {
138     final StringBuilder str = new StringBuilder();
139     for (final LayoutToken token : tokens) {
140       str.append(token);
141       str.append(";");
142     }
143     return str.toString();
144   }
145 
146 }