1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.util;
21
22 import org.apache.commons.lang.builder.ToStringBuilder;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25 import org.apache.myfaces.tobago.layout.HideLayoutToken;
26 import org.apache.myfaces.tobago.layout.LayoutToken;
27 import org.apache.myfaces.tobago.layout.LayoutTokens;
28 import org.apache.myfaces.tobago.layout.PercentLayoutToken;
29 import org.apache.myfaces.tobago.layout.PixelLayoutToken;
30 import org.apache.myfaces.tobago.layout.RelativeLayoutToken;
31
32 import java.util.ArrayList;
33 import java.util.List;
34
35
36
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
64
65
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
85
86
87
88
89
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
231 for (int i = layoutTokens.getSize() - 1; i > -1; i--) {
232
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
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
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
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
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
372 handleSpaceLeft();
373 }
374
375 if (columnsLeft() && LOG.isWarnEnabled()) {
376 handleIllegalTokens();
377 }
378 }
379
380 public String toString() {
381 return new ToStringBuilder(this).
382 append("cellLeft", cellsLeft).
383 append("spaceLeft", spaceLeft).
384 append("spaces", spaces).
385 append("layoutTokens", layoutTokens).
386 toString();
387 }
388 }
389