001 package org.apache.myfaces.tobago.util; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one or more 005 * contributor license agreements. See the NOTICE file distributed with 006 * this work for additional information regarding copyright ownership. 007 * The ASF licenses this file to You under the Apache License, Version 2.0 008 * (the "License"); you may not use this file except in compliance with 009 * the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019 020 import org.apache.commons.lang.builder.ToStringBuilder; 021 import org.slf4j.Logger; 022 import org.slf4j.LoggerFactory; 023 import org.apache.myfaces.tobago.layout.HideLayoutToken; 024 import org.apache.myfaces.tobago.layout.LayoutToken; 025 import org.apache.myfaces.tobago.layout.LayoutTokens; 026 import org.apache.myfaces.tobago.layout.PercentLayoutToken; 027 import org.apache.myfaces.tobago.layout.PixelLayoutToken; 028 import org.apache.myfaces.tobago.layout.RelativeLayoutToken; 029 030 import java.util.ArrayList; 031 import java.util.List; 032 033 /** 034 * @deprecated 035 */ 036 @Deprecated 037 public class LayoutInfo { 038 039 private static final Logger LOG = LoggerFactory.getLogger(LayoutInfo.class); 040 041 private static final int FREE = -1; 042 public static final int HIDE = -2; 043 044 private int cellsLeft; 045 private int spaceLeft; 046 private int[] spaces; 047 private LayoutTokens layoutTokens; 048 private String clientIdForLogging; 049 050 public LayoutInfo(int cellCount, int space, LayoutTokens layoutTokens, String clientIdForLogging) { 051 this(cellCount, space, layoutTokens, clientIdForLogging, false); 052 } 053 054 public LayoutInfo(int cellCount, int space, LayoutTokens layoutTokens, 055 String clientIdForLogging, boolean ignoreMismatch) { 056 057 this.cellsLeft = cellCount; 058 this.spaceLeft = space; 059 this.layoutTokens = layoutTokens; 060 this.clientIdForLogging = clientIdForLogging; 061 /*if (layoutTokens.length == cellCount) { 062 this.layoutTokens = layoutTokens; 063 } else */ 064 if (layoutTokens.getSize() > cellCount) { 065 if (!ignoreMismatch) { 066 LOG.warn("More tokens (" + layoutTokens.getSize() 067 + ") for layout than cells (" + cellCount + ") found! Ignoring" 068 + " redundant tokens. Token string was: " 069 + layoutTokens 070 + " clientId='" + clientIdForLogging + "'"); 071 } 072 073 layoutTokens.shrinkSizeTo(cellCount); 074 } else { 075 if (!ignoreMismatch && LOG.isWarnEnabled() && (cellCount - layoutTokens.getSize()) != 0) { 076 LOG.warn("More cells (" + cellCount + ") than tokens (" + layoutTokens.getSize() 077 + ") for layout found! Setting missing tokens to '1*'." 078 + " Token string was: " + layoutTokens 079 + " clientId='" + clientIdForLogging + "'"); 080 } 081 layoutTokens.ensureSize(cellCount, new RelativeLayoutToken(1)); 082 //this.layoutTokens = new String[cellCount]; 083 //for (int i = 0; i < cellCount; i++) { 084 // if (i < layoutTokens.length) { 085 // this.layoutTokens[i] = layoutTokens[i]; 086 // } else { 087 // this.layoutTokens[i] = "1*"; 088 // } 089 //} 090 } 091 createAndInitSpaces(cellCount, FREE); 092 } 093 094 private void createAndInitSpaces(int columns, int initValue) { 095 spaces = new int[columns]; 096 for (int j = 0; j < spaces.length; j++) { 097 spaces[j] = initValue; 098 } 099 } 100 101 public void update(int space, int index) { 102 update(space, index, false); 103 } 104 105 public void update(int space, int index, boolean force) { 106 if (space > spaceLeft) { 107 if (LOG.isDebugEnabled()) { 108 LOG.debug("More space (" + space + ") needed than available (" + spaceLeft + ")!" 109 + " clientId='" + clientIdForLogging + "'"); 110 } 111 if (!force) { 112 if (LOG.isDebugEnabled()) { 113 LOG.debug("Cutting to fit. " + " clientId='" + clientIdForLogging + "'"); 114 } 115 if (spaceLeft < 0) { 116 space = 0; 117 } else { 118 space = spaceLeft; 119 } 120 } 121 } 122 123 spaceLeft -= space; 124 cellsLeft--; 125 if (index < spaces.length) { 126 spaces[index] = space; 127 if (spaceLeft < 1 && columnsLeft()) { 128 if (LOG.isWarnEnabled()) { 129 LOG.warn("There are columns left but no more space! cellsLeft=" 130 + cellsLeft + ", tokens=" + layoutTokens 131 + " clientId='" + clientIdForLogging + "'"); 132 LOG.warn("calculated spaces = " + tokensToString(spaces) 133 + " clientId='" + clientIdForLogging + "'"); 134 } 135 } 136 } else { 137 LOG.warn("More space to assign (" + space + "px) but no more columns!" 138 + " More layout tokens than column tags?" + " clientId='" + clientIdForLogging + "'"); 139 } 140 } 141 142 public boolean columnsLeft() { 143 return cellsLeft > 0; 144 } 145 146 147 public void handleIllegalTokens() { 148 for (int i = 0; i < spaces.length; i++) { 149 if (isFree(i)) { 150 if (LOG.isWarnEnabled()) { 151 LOG.warn("Illegal layout token pattern \"" + layoutTokens.get(i) 152 + "\" ignored, set to 0px !" + " clientId='" + clientIdForLogging + "'"); 153 } 154 spaces[i] = 0; 155 } 156 } 157 } 158 159 160 public static String listToTokenString(List list) { 161 String[] tokens = new String[list.size()]; 162 for (int i = 0; i < list.size(); i++) { 163 tokens[i] = list.get(i).toString(); 164 } 165 return tokensToString(tokens); 166 } 167 168 public static String tokensToString(int[] tokens) { 169 String[] strings = new String[tokens.length]; 170 for (int i = 0; i < tokens.length; i++) { 171 strings[i] = Integer.toString(tokens[i]); 172 } 173 return tokensToString(strings); 174 } 175 176 public static String tokensToString(String[] tokens) { 177 StringBuilder sb = new StringBuilder(); 178 for (String token : tokens) { 179 if (sb.length() != 0) { 180 sb.append(";"); 181 } 182 sb.append(token); 183 } 184 sb.insert(0, "\""); 185 sb.append("\""); 186 return sb.toString(); 187 } 188 189 public boolean isFree(int column) { 190 return spaces[column] == FREE; 191 } 192 193 public int getSpaceLeft() { 194 return spaceLeft; 195 } 196 197 public LayoutTokens getLayoutTokens() { 198 return layoutTokens; 199 } 200 201 public boolean hasLayoutTokens() { 202 return !layoutTokens.isEmpty(); 203 } 204 205 public List<Integer> getSpaceList() { 206 List<Integer> list = new ArrayList<Integer>(spaces.length); 207 for (int space : spaces) { 208 list.add(space); 209 } 210 return list; 211 } 212 213 public void handleSpaceLeft() { 214 if (spaceLeft > 0) { 215 if (LOG.isDebugEnabled()) { 216 LOG.debug("spread spaceLeft (" + spaceLeft + "px) to columns" + " clientId='" + clientIdForLogging + "'"); 217 LOG.debug("spaces before spread :" + arrayAsString(spaces) + " clientId='" + clientIdForLogging + "'"); 218 } 219 220 for (int i = 0; i < layoutTokens.getSize(); i++) { 221 if (layoutTokens.get(i) instanceof RelativeLayoutToken) { 222 addSpace(spaceLeft, i); 223 break; 224 } 225 } 226 boolean found = false; 227 while (spaceLeft > 0) { 228 // for (int i = 0; i < layoutTokens.length; i++) { 229 for (int i = layoutTokens.getSize() - 1; i > -1; i--) { 230 //String layoutToken = layoutTokens[i]; 231 if (spaceLeft > 0 && layoutTokens.get(i) instanceof RelativeLayoutToken) { 232 found = true; 233 addSpace(1, i); 234 } 235 } 236 if (!found) { 237 break; 238 } 239 } 240 } 241 if (spaceLeft > 0 && LOG.isWarnEnabled()) { 242 LOG.warn("Space left after spreading : " + spaceLeft + "px!" + " clientId='" + clientIdForLogging + "'"); 243 } 244 if (LOG.isDebugEnabled()) { 245 LOG.debug("spaces after spread :" + arrayAsString(spaces) + " clientId='" + clientIdForLogging + "'"); 246 } 247 } 248 249 //TODO replace with Arrays.asList .. 250 private String arrayAsString(int[] currentSpaces) { 251 StringBuilder sb = new StringBuilder("["); 252 for (int currentSpace : currentSpaces) { 253 sb.append(currentSpace); 254 sb.append(", "); 255 } 256 sb.replace(sb.lastIndexOf(", "), sb.length(), "]"); 257 return sb.toString(); 258 } 259 260 private void addSpace(int space, int i) { 261 if (spaces[i] > HIDE) { 262 if (spaces[i] == FREE) { 263 spaces[i] = space; 264 } else { 265 spaces[i] += space; 266 } 267 spaceLeft -= space; 268 } 269 } 270 271 272 private void parsePortions(int portions) { 273 if (columnsLeft()) { 274 275 // 2. calc and set portion 276 if (portions > 0) { 277 int widthForPortions = getSpaceLeft(); 278 for (int i = 0; i < layoutTokens.getSize(); i++) { 279 LayoutToken token = layoutTokens.get(i); 280 if (isFree(i) && token instanceof RelativeLayoutToken) { 281 int portion = ((RelativeLayoutToken) token).getFactor(); 282 float w = (float) widthForPortions / portions * portion; 283 if (w < 0) { 284 update(0, i); 285 if (LOG.isDebugEnabled()) { 286 LOG.debug("set column " + i + " from " + token 287 + " to with " + w + " == 0px" + " clientId='" + clientIdForLogging + "'"); 288 } 289 } else { 290 update(Math.round(w), i); 291 if (LOG.isDebugEnabled()) { 292 LOG.debug("set column " + i + " from " + token 293 + " to with " + w + " == " + Math.round(w) + "px" + " clientId='" + clientIdForLogging + "'"); 294 } 295 } 296 } 297 } 298 } 299 } 300 } 301 302 /* 303 public void parseAsterisks() { 304 String[] tokens = getLayoutTokens(); 305 if (columnsLeft()) { 306 // 1. count unset columns 307 int portions = 0; 308 for (int i = 0; i < tokens.length; i++) { 309 if (isFree(i) && tokens[i].equals("*")) { 310 portions++; 311 } 312 } 313 // 2. calc and set portion 314 int widthPerPortion; 315 if (portions > 0) { 316 widthPerPortion = getSpaceLeft() / portions; 317 for (int i = 0; i < tokens.length; i++) { 318 if (isFree(i) && tokens[i].equals("*")) { 319 int w = widthPerPortion; 320 update(w, i); 321 if (LOG.isDebugEnabled()) { 322 LOG.debug("set column " + i + " from " + tokens[i] 323 + " to with " + w); 324 } 325 } 326 } 327 } 328 } 329 } 330 */ 331 332 public void parseColumnLayout(double space) { 333 parseColumnLayout(space, 0); 334 } 335 336 public void parseColumnLayout(double space, int padding) { 337 338 if (hasLayoutTokens()) { 339 int portions = 0; 340 for (int i = 0; i < layoutTokens.getSize(); i++) { 341 LayoutToken token = layoutTokens.get(i); 342 if (token instanceof HideLayoutToken) { 343 update(0, i); 344 spaces[i] = HIDE; 345 if (LOG.isDebugEnabled()) { 346 LOG.debug("set column " + i + " from " + layoutTokens.get(i) 347 + " to hide " + " clientId='" + clientIdForLogging + "'"); 348 } 349 } else if (token instanceof PixelLayoutToken) { 350 int w = ((PixelLayoutToken) token).getPixel(); 351 update(w, i, true); 352 if (LOG.isDebugEnabled()) { 353 LOG.debug("set column " + i + " from " + token 354 + " to with " + w + " clientId='" + clientIdForLogging + "'"); 355 } 356 } else if (token instanceof RelativeLayoutToken) { 357 portions += ((RelativeLayoutToken) token).getFactor(); 358 } else if (token instanceof PercentLayoutToken) { 359 int percent = ((PercentLayoutToken) token).getPercent(); 360 int w = (int) (space / 100 * percent); 361 update(w, i); 362 if (LOG.isDebugEnabled()) { 363 LOG.debug("set column " + i + " from " + token 364 + " to with " + w + " clientId='" + clientIdForLogging + "'"); 365 } 366 } 367 } 368 parsePortions(portions); 369 // parseAsterisks(); 370 handleSpaceLeft(); 371 } 372 373 if (columnsLeft() && LOG.isWarnEnabled()) { 374 handleIllegalTokens(); 375 } 376 } 377 378 public String toString() { 379 return new ToStringBuilder(this). 380 append("cellLeft", cellsLeft). 381 append("spaceLeft", spaceLeft). 382 append("spaces", spaces). 383 append("layoutTokens", layoutTokens). 384 toString(); 385 } 386 } 387