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.util;
21  
22  import org.apache.myfaces.tobago.layout.HideLayoutToken;
23  import org.apache.myfaces.tobago.layout.LayoutToken;
24  import org.apache.myfaces.tobago.layout.LayoutTokens;
25  import org.apache.myfaces.tobago.layout.PercentLayoutToken;
26  import org.apache.myfaces.tobago.layout.PixelLayoutToken;
27  import org.apache.myfaces.tobago.layout.RelativeLayoutToken;
28  import org.slf4j.Logger;
29  import org.slf4j.LoggerFactory;
30  
31  import java.util.ArrayList;
32  import java.util.Arrays;
33  import java.util.List;
34  
35  /**
36   * @deprecated
37   */
38  @Deprecated
39  public class LayoutInfo {
40  
41    private static final Logger LOG = LoggerFactory.getLogger(LayoutInfo.class);
42  
43    private static final int FREE = -1;
44    public static final int HIDE = -2;
45  
46    private int cellsLeft;
47    private int spaceLeft;
48    private int[] spaces;
49    private LayoutTokens layoutTokens;
50    private String clientIdForLogging;
51  
52    public LayoutInfo(int cellCount, int space, LayoutTokens layoutTokens, String clientIdForLogging) {
53      this(cellCount, space, layoutTokens, clientIdForLogging, false);
54    }
55  
56    public LayoutInfo(int cellCount, int space, LayoutTokens layoutTokens,
57        String clientIdForLogging, boolean ignoreMismatch) {
58  
59      this.cellsLeft = cellCount;
60      this.spaceLeft = space;
61      this.layoutTokens = layoutTokens;
62      this.clientIdForLogging = clientIdForLogging;
63      /*if (layoutTokens.length == cellCount) {
64        this.layoutTokens = layoutTokens;
65      } else */
66      if (layoutTokens.getSize() > cellCount) {
67        if (!ignoreMismatch) {
68          LOG.warn("More tokens (" + layoutTokens.getSize()
69              + ") for layout than cells (" + cellCount + ") found! Ignoring"
70              + " redundant tokens. Token string was: "
71              + layoutTokens
72              + " clientId='" + clientIdForLogging + "'");
73        }
74  
75        layoutTokens.shrinkSizeTo(cellCount);
76      } else {
77        if (!ignoreMismatch && LOG.isWarnEnabled() && (cellCount - layoutTokens.getSize()) != 0) {
78          LOG.warn("More cells (" + cellCount + ") than tokens (" + layoutTokens.getSize()
79              + ") for layout found! Setting missing tokens to '1*'."
80              + " Token string was: " + layoutTokens
81              + " clientId='" + clientIdForLogging + "'");
82        }
83        layoutTokens.ensureSize(cellCount, new RelativeLayoutToken(1));
84        //this.layoutTokens = new String[cellCount];
85        //for (int i = 0; i < cellCount; i++) {
86        //  if (i < layoutTokens.length) {
87        //    this.layoutTokens[i] = layoutTokens[i];
88        //  } else {
89        //    this.layoutTokens[i] = "1*";
90        //  }
91        //}
92      }
93      createAndInitSpaces(cellCount, FREE);
94    }
95  
96    private void createAndInitSpaces(int columns, int initValue) {
97      spaces = new int[columns];
98      for (int j = 0; j < spaces.length; j++) {
99        spaces[j] = initValue;
100     }
101   }
102 
103   public void update(int space, int index) {
104     update(space, index, false);
105   }
106 
107   public void update(int space, int index, boolean force) {
108     if (space > spaceLeft) {
109       if (LOG.isDebugEnabled()) {
110         LOG.debug("More space (" + space + ") needed than available (" + spaceLeft + ")!"
111             + " clientId='" + clientIdForLogging + "'");
112       }
113       if (!force) {
114         if (LOG.isDebugEnabled()) {
115           LOG.debug("Cutting to fit. " + " clientId='" + clientIdForLogging + "'");
116         }
117         if (spaceLeft < 0) {
118           space = 0;
119         } else {
120           space = spaceLeft;
121         }
122       }
123     }
124 
125     spaceLeft -= space;
126     cellsLeft--;
127     if (index < spaces.length) {
128       spaces[index] = space;
129       if (spaceLeft < 1 && columnsLeft()) {
130         if (LOG.isWarnEnabled()) {
131           LOG.warn("There are columns left but no more space! cellsLeft="
132               + cellsLeft + ", tokens=" + layoutTokens
133               + " clientId='" + clientIdForLogging + "'");
134           LOG.warn("calculated spaces = " + tokensToString(spaces)
135               + " clientId='" + clientIdForLogging + "'");
136         }
137       }
138     } else {
139       LOG.warn("More space to assign (" + space + "px) but no more columns!"
140           + " More layout tokens than column tags?" + " clientId='" + clientIdForLogging + "'");
141     }
142   }
143 
144   public boolean columnsLeft() {
145     return cellsLeft > 0;
146   }
147 
148 
149   public void handleIllegalTokens() {
150     for (int i = 0; i < spaces.length; i++) {
151       if (isFree(i)) {
152         if (LOG.isWarnEnabled()) {
153           LOG.warn("Illegal layout token pattern \"" + layoutTokens.get(i)
154               + "\" ignored, set to 0px !" + " clientId='" + clientIdForLogging + "'");
155         }
156         spaces[i] = 0;
157       }
158     }
159   }
160 
161 
162   public static String listToTokenString(List list) {
163     String[] tokens = new String[list.size()];
164     for (int i = 0; i < list.size(); i++) {
165       tokens[i] = list.get(i).toString();
166     }
167     return tokensToString(tokens);
168   }
169 
170   public static String tokensToString(int[] tokens) {
171     String[] strings = new String[tokens.length];
172     for (int i = 0; i < tokens.length; i++) {
173       strings[i] = Integer.toString(tokens[i]);
174     }
175     return tokensToString(strings);
176   }
177 
178   public static String tokensToString(String[] tokens) {
179     StringBuilder sb = new StringBuilder();
180     for (String token : tokens) {
181       if (sb.length() != 0) {
182         sb.append(";");
183       }
184       sb.append(token);
185     }
186     sb.insert(0, "\"");
187     sb.append("\"");
188     return sb.toString();
189   }
190 
191   public boolean isFree(int column) {
192     return spaces[column] == FREE;
193   }
194 
195   public int getSpaceLeft() {
196     return spaceLeft;
197   }
198 
199   public LayoutTokens getLayoutTokens() {
200     return layoutTokens;
201   }
202 
203   public boolean hasLayoutTokens() {
204     return !layoutTokens.isEmpty();
205   }
206 
207   public List<Integer> getSpaceList() {
208     List<Integer> list = new ArrayList<Integer>(spaces.length);
209     for (int space : spaces) {
210       list.add(space);
211     }
212     return list;
213   }
214 
215   public void handleSpaceLeft() {
216     if (spaceLeft > 0) {
217       if (LOG.isDebugEnabled()) {
218         LOG.debug("spread spaceLeft (" + spaceLeft + "px) to columns" + " clientId='" + clientIdForLogging + "'");
219         LOG.debug("spaces before spread :" + arrayAsString(spaces) + " clientId='" + clientIdForLogging + "'");
220       }
221 
222       for (int i = 0; i < layoutTokens.getSize(); i++) {
223         if (layoutTokens.get(i) instanceof RelativeLayoutToken) {
224           addSpace(spaceLeft, i);
225           break;
226         }
227       }
228       boolean found = false;
229       while (spaceLeft > 0) {
230 //        for (int i = 0; i < layoutTokens.length; i++) {
231         for (int i = layoutTokens.getSize() - 1; i > -1; i--) {
232           //String layoutToken = layoutTokens[i];
233           if (spaceLeft > 0 && layoutTokens.get(i) instanceof RelativeLayoutToken) {
234             found = true;
235             addSpace(1, i);
236           }
237         }
238         if (!found) {
239           break;
240         }
241       }
242     }
243     if (spaceLeft > 0 && LOG.isWarnEnabled()) {
244       LOG.warn("Space left after spreading : " + spaceLeft + "px!" + " clientId='" + clientIdForLogging + "'");
245     }
246     if (LOG.isDebugEnabled()) {
247       LOG.debug("spaces after spread  :" + arrayAsString(spaces) + " clientId='" + clientIdForLogging + "'");
248     }
249   }
250 
251   //TODO replace with Arrays.asList ..
252   private String arrayAsString(int[] currentSpaces) {
253     StringBuilder sb = new StringBuilder("[");
254     for (int currentSpace : currentSpaces) {
255       sb.append(currentSpace);
256       sb.append(", ");
257     }
258     sb.replace(sb.lastIndexOf(", "), sb.length(), "]");
259     return sb.toString();
260   }
261 
262   private void addSpace(int space, int i) {
263     if (spaces[i] > HIDE) {
264       if (spaces[i] == FREE) {
265         spaces[i] = space;
266       } else {
267         spaces[i] += space;
268       }
269       spaceLeft -= space;
270     }
271   }
272 
273 
274   private void parsePortions(int portions) {
275     if (columnsLeft()) {
276 
277       //  2. calc and set portion
278       if (portions > 0) {
279         int widthForPortions = getSpaceLeft();
280         for (int i = 0; i < layoutTokens.getSize(); i++) {
281           LayoutToken token = layoutTokens.get(i);
282           if (isFree(i) && token instanceof RelativeLayoutToken) {
283             int portion = ((RelativeLayoutToken) token).getFactor();
284             float w = (float) widthForPortions / portions * portion;
285             if (w < 0) {
286               update(0, i);
287               if (LOG.isDebugEnabled()) {
288                 LOG.debug("set column " + i + " from " + token
289                     + " to with " + w + " == 0px" + " clientId='" + clientIdForLogging + "'");
290               }
291             } else {
292               update(Math.round(w), i);
293               if (LOG.isDebugEnabled()) {
294                 LOG.debug("set column " + i + " from " + token
295                     + " to with " + w + " == " + Math.round(w) + "px" + " clientId='" + clientIdForLogging + "'");
296               }
297             }
298           }
299         }
300       }
301     }
302   }
303 
304 /*
305   public void parseAsterisks() {
306     String[] tokens = getLayoutTokens();
307     if (columnsLeft()) {
308       //  1. count unset columns
309       int portions = 0;
310       for (int i = 0; i < tokens.length; i++) {
311         if (isFree(i) && tokens[i].equals("*")) {
312           portions++;
313         }
314       }
315       //  2. calc and set portion
316       int widthPerPortion;
317       if (portions > 0) {
318         widthPerPortion = getSpaceLeft() / portions;
319         for (int i = 0; i < tokens.length; i++) {
320           if (isFree(i) && tokens[i].equals("*")) {
321             int w = widthPerPortion;
322             update(w, i);
323             if (LOG.isDebugEnabled()) {
324               LOG.debug("set column " + i + " from " + tokens[i]
325                   + " to with " + w);
326             }
327           }
328         }
329       }
330     }
331   }
332 */
333 
334   public void parseColumnLayout(double space) {
335     parseColumnLayout(space, 0);
336   }
337 
338   public void parseColumnLayout(double space, int padding) {
339 
340     if (hasLayoutTokens()) {
341       int portions = 0;
342       for (int i = 0; i < layoutTokens.getSize(); i++) {
343         LayoutToken token = layoutTokens.get(i);
344         if (token instanceof HideLayoutToken) {
345           update(0, i);
346           spaces[i] = HIDE;
347           if (LOG.isDebugEnabled()) {
348             LOG.debug("set column " + i + " from " + layoutTokens.get(i)
349                 + " to hide " + " clientId='" + clientIdForLogging + "'");
350           }
351         } else if (token instanceof PixelLayoutToken) {
352           int w = ((PixelLayoutToken) token).getPixel();
353           update(w, i, true);
354           if (LOG.isDebugEnabled()) {
355             LOG.debug("set column " + i + " from " + token
356                 + " to with " + w + " clientId='" + clientIdForLogging + "'");
357           }
358         } else if (token instanceof RelativeLayoutToken) {
359           portions += ((RelativeLayoutToken) token).getFactor();
360         } else if (token instanceof PercentLayoutToken) {
361           int percent = ((PercentLayoutToken) token).getPercent();
362           int w = (int) (space / 100 * percent);
363           update(w, i);
364           if (LOG.isDebugEnabled()) {
365             LOG.debug("set column " + i + " from " + token
366                 + " to with " + w + " clientId='" + clientIdForLogging + "'");
367           }
368         }
369       }
370       parsePortions(portions);
371 //      parseAsterisks();
372       handleSpaceLeft();
373     }
374 
375     if (columnsLeft() && LOG.isWarnEnabled()) {
376       handleIllegalTokens();
377     }
378   }
379 
380   @Override
381   public String toString() {
382     return "LayoutInfo{"
383         + "cellsLeft=" + cellsLeft
384         + ", spaceLeft=" + spaceLeft
385         + ", spaces=" + Arrays.toString(spaces)
386         + ", layoutTokens=" + layoutTokens
387         + '}';
388   }
389 }