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