1 package fr.improve.struts.taglib.layout.collection; 2 3 import java.lang.reflect.InvocationTargetException ; 4 import java.lang.reflect.Method ; 5 import java.text.DecimalFormat ; 6 import java.text.NumberFormat ; 7 import java.util.ArrayList ; 8 import java.util.HashMap ; 9 import java.util.Iterator ; 10 import java.util.List ; 11 import java.util.Map ; 12 13 import javax.servlet.http.HttpServletResponse ; 14 import javax.servlet.jsp.JspException ; 15 16 import org.apache.struts.taglib.html.Constants; 17 import org.apache.struts.util.RequestUtils; 18 19 import fr.improve.struts.taglib.layout.collection.header.MultiLevelHeader; 20 import fr.improve.struts.taglib.layout.el.Expression; 21 import fr.improve.struts.taglib.layout.event.StaticCodeIncludeLayoutEvent; 22 import fr.improve.struts.taglib.layout.event.StaticCodeIncludeListener; 23 import fr.improve.struts.taglib.layout.sort.SortUtil; 24 import fr.improve.struts.taglib.layout.util.IFooterRenderer; 25 import fr.improve.struts.taglib.layout.util.IMathCollectionRenderer; 26 import fr.improve.struts.taglib.layout.util.IMultiLevelHeaderRenderer; 27 import fr.improve.struts.taglib.layout.util.LayoutUtils; 28 29 30 31 37 public class CollectionTag extends BaseCollectionTag implements StaticCodeIncludeListener { 38 41 static Class mathClass; 42 43 static { 44 try { 45 mathClass = RequestUtils.applicationClass("org.apache.commons.math.stat.StatUtils"); 46 } catch (ClassNotFoundException e) { 47 } 49 } 50 51 54 private String staticCode = ""; 55 56 59 protected Map numbers = new HashMap (); 60 61 64 protected void reset() { 65 numbers.clear(); 66 super.reset(); 67 } 68 75 protected void storeMathData(double in_value) throws JspException { 76 if (!isFirst()) { 77 int lc_ligne = getIndex(); 78 int lc_col = getColumn(); 79 Object bean = getBean(); 80 String property = ((ItemContext)headers.get(lc_col)).getProperty(); 81 String mathOp = ((ItemContext)headers.get(lc_col)).getMathOperation(); 82 if (mathOp!=null) { 83 String key = String.valueOf(lc_col); 84 if (!numbers.containsKey(key)){ 85 double[] lc_list = new double[size]; numbers.put(key,lc_list); 87 } 88 double[] lc_list = (double[]) numbers.get(key); 89 lc_list[index-1] = in_value; 90 } 91 } 92 } 93 101 protected String doMathOperation(String in_operation, double[] in_data, String in_mathPattern) throws JspException { 102 if (in_data!=null && in_operation!=null && in_operation.length()>0){ 103 double total = computeMathResult(in_operation, in_data); 104 if (in_mathPattern!=null){ 105 NumberFormat lc_format = new DecimalFormat (in_mathPattern); 106 return lc_format.format(total); 107 } 108 return String.valueOf(total); 109 } 110 return null; 111 } 112 120 protected double computeMathResult(String in_operation, double[] in_data) throws JspException { 121 if (mathClass==null) { 122 throw new IllegalStateException ("Math operation is not available, please put commons-math.jar in the classpath"); 123 } 124 Method m; 125 try { 126 m = mathClass.getMethod(in_operation, new Class []{double[].class}); 127 } catch (NoSuchMethodException e) { 128 throw new IllegalArgumentException ("Math operation " + in_operation + " is not supported"); 129 } 130 Double result = null; 131 try { 132 result = (Double ) m.invoke(null,new Object []{in_data}); 133 } catch (InvocationTargetException e) { 134 throw new JspException ("Math operation " + in_operation + " failed : " + e.getMessage()); 136 } catch (IllegalAccessException e) { 137 throw new JspException ("Math operation " + in_operation + " failed : " + e.getMessage()); 139 } 140 return result.doubleValue(); 141 } 143 144 145 146 149 protected void addItem(StringBuffer in_buffer, String in_item, String in_url, String in_target, String in_onclick) throws JspException { 150 if (in_url==null) { 152 renderItem(in_buffer, in_item); 153 } else { 154 StringBuffer lc_buffer = new StringBuffer (); 155 String lc_item = in_item; 156 if (sortType==SORT_JAVASCRIPT) { 157 if (lc_item.startsWith("<!--")) { 158 int lc_index = lc_item.indexOf("-->"); 161 lc_buffer.append(lc_item.substring(0, lc_index +3)); 162 lc_item = lc_item.substring(lc_index+3); 163 } else { 164 lc_buffer.append("<!-- "); 166 lc_buffer.append(in_item); 167 lc_buffer.append("-->"); 168 } 169 } 170 171 lc_buffer.append("<a HREF=\""); 172 lc_buffer.append(((HttpServletResponse )pageContext.getResponse()).encodeURL(in_url)); 173 if (in_onclick!=null) { 174 lc_buffer.append("\" onClick=\""); 175 lc_buffer.append(Expression.evaluate(in_onclick, pageContext)); 176 } 177 if (in_target!=null) { 178 lc_buffer.append("\" target=\""); 179 lc_buffer.append(in_target); 180 } 181 String lc_styleClass = styleClass; 182 if (tempStyleClass != null) lc_styleClass = tempStyleClass; 183 if (lc_styleClass != null) { 184 lc_buffer.append("\" class=\""); 185 lc_buffer.append(lc_styleClass); 186 } 187 lc_buffer.append("\">"); 188 lc_buffer.append(lc_item); 189 lc_buffer.append("</a>"); 190 renderItem(in_buffer, lc_buffer.toString()); 191 } 192 } 193 194 195 protected void renderBlankCollection(StringBuffer in_buffer) throws JspException { 196 panel.doPrintEmptyCollection(in_buffer, LayoutUtils.getLabel(pageContext, getBundle(), emptyKey, null, false)); 197 } 198 protected void renderEnd(StringBuffer buffer) throws JspException { 200 renderMathData(buffer); 201 renderFooter(buffer); 202 panel.doEndPanel(buffer); 203 renderStaticCode(buffer); 204 } 205 206 211 protected void renderMathData(StringBuffer in_buffer) throws JspException { 212 if (!(panel instanceof IMathCollectionRenderer)) { 213 return; 214 } 215 IMathCollectionRenderer lc_renderer = (IMathCollectionRenderer) panel; 216 217 boolean started = false; 219 int consecutiveNull = 0; 221 String uniqueParam = mathOperationId; 222 int lc_nbOfSpan = 0; 223 for (int i=0; i < headers.size(); i++) { 224 ItemContext lc_header = (ItemContext) headers.get(i); 225 String lc_operation = lc_header.getMathOperation(); 226 String lc_mathStyleClass = tempStyleClass!=null ? tempStyleClass : styleClass; 227 String lc_mathPattern = lc_header.getMathPattern(); 228 double[] data = (double[])numbers.get(String.valueOf(i)); 229 String lc_data = doMathOperation(lc_operation,data,lc_mathPattern); 230 String resultId = CollectionInputTag.MATH_ID_PREFIX + "t" + uniqueParam + "r" + i; 232 233 if (lc_operation==null) { 235 consecutiveNull++; 236 } else { 237 if (!started){ 238 lc_renderer.startMathData(in_buffer); 240 started = true; 241 } 242 243 if (consecutiveNull>0) { 245 lc_renderer.renderMathData(in_buffer, " ", consecutiveNull, null,lc_mathStyleClass); 246 lc_nbOfSpan = lc_nbOfSpan + consecutiveNull; 247 } 248 249 lc_renderer.renderMathData(in_buffer, lc_data, 1, resultId,lc_mathStyleClass); 251 consecutiveNull = 0; 252 lc_nbOfSpan = lc_nbOfSpan + 1; 253 } 254 } 255 if (started) { 256 if (headers.size()-lc_nbOfSpan>0){ 257 lc_renderer.renderMathData(in_buffer, " ", headers.size()-lc_nbOfSpan, null,styleClass); 258 } 259 lc_renderer.endMathData(in_buffer); 261 } 262 263 } 264 265 268 protected void renderFooter(StringBuffer in_buffer) throws JspException { 269 if (!(panel instanceof IFooterRenderer)) { 271 return; 272 } 273 IFooterRenderer lc_renderer = (IFooterRenderer) panel; 274 275 boolean started = false; 277 278 int consecutiveNull = 0; 280 281 for (int i=0; i < headers.size(); i++) { 282 ItemContext lc_header = (ItemContext) headers.get(i); 283 String lc_footer = lc_header.getFooter(); 284 if (lc_footer==null) { 285 consecutiveNull++; 286 } else { 287 if (!started){ 288 lc_renderer.startFooter(in_buffer); 290 started = true; 291 } 292 293 if (consecutiveNull>0) { 295 lc_renderer.printFooterElement(in_buffer, " ", consecutiveNull); 296 } 297 298 Object [] lc_args = new Object [5]; 300 lc_args[0] = Expression.evaluate(lc_header.getFooterArg0(), pageContext); 301 lc_args[1] = Expression.evaluate(lc_header.getFooterArg1(), pageContext); 302 String lc_label = LayoutUtils.getLabel(pageContext, getBundle(), lc_footer, lc_args, false); 303 lc_renderer.printFooterElement(in_buffer, lc_label, 1); 304 consecutiveNull = 0; 305 306 } 307 } 308 309 if (started) { 310 lc_renderer.endFooter(in_buffer); 312 } 313 } 314 315 316 320 protected void renderHeader(StringBuffer buffer, ItemContext in_header) throws JspException { 321 322 String lc_key = in_header.getTitle(); 324 String lc_arg0 = Expression.evaluate(in_header.getArg0(), pageContext); 325 String lc_arg1 = Expression.evaluate(in_header.getArg1(), pageContext); 326 Object [] lc_args = new Object [2]; 327 lc_args[0] = lc_arg0; 328 lc_args[1] = lc_arg1; 329 String lc_title = LayoutUtils.getLabel(pageContext, getBundle(), lc_key, lc_args, false); 330 331 String lc_sortUrl = computeSortUrl(in_header.getSortProperty()); 333 334 panel.doPrintHeader(buffer, lc_title, in_header.getWidth(), lc_sortUrl); 336 } 337 338 protected String computeSortUrl(String in_sortProperty) { 339 String lc_sortUrl = null; 340 if (in_sortProperty!=null) { 341 StringBuffer lc_tempBuffer = new StringBuffer (); 342 switch (sortType) { 343 case SORT_LAYOUT: 344 String lc_unEncodedUrl = SortUtil.getURLForCollection(in_sortProperty, (javax.servlet.http.HttpServletRequest ) pageContext.getRequest()); 345 lc_tempBuffer.append(((HttpServletResponse )pageContext.getResponse()).encodeURL(lc_unEncodedUrl)); 346 break; 347 case SORT_CUSTOM: 348 if (! sortAction.toLowerCase().startsWith("javascript:")) { 350 lc_tempBuffer.append(sortAction); 352 if (sortAction.indexOf("?")!=-1) lc_tempBuffer.append("&"); else lc_tempBuffer.append("?"); 353 lc_tempBuffer.append(sortParam); 354 lc_tempBuffer.append("="); 355 lc_tempBuffer.append(in_sortProperty); 356 } else { 357 String javascriptSortParamName = "sortParam"; 359 if (sortParam != null && sortParam.trim().length() > 0) { 360 javascriptSortParamName = sortParam; 361 } 362 pageContext.setAttribute(javascriptSortParamName, in_sortProperty); 363 lc_tempBuffer.append(Expression.evaluate(sortAction, pageContext)); 364 pageContext.removeAttribute(javascriptSortParamName); 365 } 366 break; 367 case SORT_JAVASCRIPT: 368 lc_tempBuffer.append("javascript:arraySort("); 370 lc_tempBuffer.append(sortParam); 371 lc_tempBuffer.append(","); 372 lc_tempBuffer.append(column); 373 lc_tempBuffer.append(","); 374 lc_tempBuffer.append(size); 375 lc_tempBuffer.append(","); 376 lc_tempBuffer.append(nbOfColumns); 377 lc_tempBuffer.append(")"); 378 break; 379 } 380 lc_sortUrl = lc_tempBuffer.toString(); 381 } 382 return lc_sortUrl; 383 } 384 385 private MultiLevelHeader currentHeader; 386 387 391 protected void renderMultiLevelHeaders(StringBuffer in_buffer, List in_multiLevelHeaders, int in_level) throws JspException { 392 if (in_multiLevelHeaders!=null) { 393 List lc_nestedLevels = null; 394 Iterator lc_it = in_multiLevelHeaders.iterator(); 395 IMultiLevelHeaderRenderer lc_panel = (IMultiLevelHeaderRenderer) panel; 396 column = 0; 397 398 boolean lc_started = false; 400 401 while (lc_it.hasNext()) { 402 MultiLevelHeader lc_header = (MultiLevelHeader) lc_it.next(); 403 List lc_headerChildren = lc_header.getChildHeaders(); 404 int lc_rowSpan = lc_headerChildren!=null ? 1 : in_level+1 - lc_header.getLevel(); 405 406 Object [] lc_args = new Object [2]; 407 lc_args[0] = Expression.evaluate(lc_header.getArg0(), pageContext); 408 lc_args[1] = Expression.evaluate(lc_header.getArg1(), pageContext); 409 String lc_title = LayoutUtils.getLabel(pageContext, getBundle(), lc_header.getTitle(), lc_args, false); 410 String lc_sortUrl = computeSortUrl(lc_header.getSortProperty()); 411 String lc_styleClass = lc_header.getStyleClass()==null ? getStyleClass() : lc_header.getStyleClass(); 412 String lc_tooltip = LayoutUtils.getLabel(pageContext, getBundle(), lc_header.getTooltip(), null, false); 413 currentHeader = lc_header; 414 415 if (lc_title!=null) { 416 418 if (!lc_started) { 419 lc_panel.startMultiLevelHeaderRow(in_buffer); 421 lc_started = true; 422 } 423 424 lc_panel.renderMultiLevelHeader(in_buffer, lc_title, lc_sortUrl, lc_styleClass, lc_header.getColSpan(), lc_rowSpan, lc_header.getWidth()); 426 } 427 currentHeader = null; 428 if (lc_headerChildren!=null) { 429 if (lc_nestedLevels==null) { 430 lc_nestedLevels = new ArrayList (); 431 } 432 lc_nestedLevels.addAll(lc_headerChildren); 433 } 434 column++; 435 } 436 if(lc_started) { 437 lc_panel.endMultiLevelHeaderRow(in_buffer); 438 } 439 renderMultiLevelHeaders(in_buffer, lc_nestedLevels, in_level-1); 440 } 441 } 442 443 public MultiLevelHeader getCurrentHeader() { 444 return currentHeader; 445 } 446 447 protected void renderItem(StringBuffer buffer, String in_item) throws JspException { 448 449 String lc_item = in_item; 450 451 if (needSelect && !selectHidden) { 453 StringBuffer lc_tempBuffer = new StringBuffer (); 454 if (sortType==SORT_JAVASCRIPT && lc_item.startsWith("<!--")) { 455 int lc_index = lc_item.indexOf("-->"); 458 lc_tempBuffer.append(lc_item.substring(0, lc_index +3)); 459 lc_item = lc_item.substring(lc_index+3); 460 } 461 renderSelection(lc_tempBuffer); 462 needSelect = false; 463 lc_tempBuffer.append(lc_item); 464 lc_item = lc_tempBuffer.toString(); 465 } 466 467 468 String [] lc_styleClasses = new String [1 + tempStyles.size()]; 469 lc_styleClasses[0] = tempStyleClass!=null ? tempStyleClass : styleClass; 470 for (int i=0; i < tempStyles.size(); i++) { 471 lc_styleClasses[i+1] = (String ) tempStyles.get(i); 472 } 473 474 panel.doPrintItem(buffer, lc_item, lc_styleClasses, sortType==SORT_JAVASCRIPT ? "t" + sortParam + "l" + index + "c" + column : null); 475 } 476 477 protected void renderSelection(StringBuffer lc_tempBuffer) throws JspException { 478 lc_tempBuffer.append("<input type=\""); 479 if ("checkbox".equalsIgnoreCase(selectType)) { 480 lc_tempBuffer.append("checkbox"); 481 } else { 482 lc_tempBuffer.append("radio"); 483 } 484 lc_tempBuffer.append("\" name=\""); 485 if (selectName!=null) { 486 lc_tempBuffer.append(selectName); 487 } else { 488 lc_tempBuffer.append(selectProperty); 489 } 490 if ("checkbox".equalsIgnoreCase(selectType)) { 491 if (selectId!=null) { 492 lc_tempBuffer.append("("); 493 lc_tempBuffer.append(LayoutUtils.getProperty(bean, selectId)); 494 lc_tempBuffer.append(")"); 495 } else { 496 lc_tempBuffer.append("["); 497 lc_tempBuffer.append(index-1); 498 lc_tempBuffer.append("]"); 499 if (selectIndex!=null) { 500 lc_tempBuffer.append("."); 501 lc_tempBuffer.append(selectIndex); 502 } 503 } 504 } 505 506 if (onClick!=null) { 507 lc_tempBuffer.append("\" onclick=\""); 508 lc_tempBuffer.append(onClick); 509 } 510 511 lc_tempBuffer.append("\" value=\""); 512 Object lc_value = LayoutUtils.getProperty(bean, selectProperty); 513 lc_tempBuffer.append(lc_value); 514 lc_tempBuffer.append("\""); 515 516 if (isCurrentBeanSelected()) { 518 lc_tempBuffer.append(" checked"); 519 } 520 521 lc_tempBuffer.append(">"); 522 } 523 524 protected void renderStart(StringBuffer out_buffer) throws JspException { 525 Object [] lc_args = new Object [5]; 528 Object lc_arg0 = null; 529 if (arg0Name!=null) { 530 lc_arg0 = LayoutUtils.getBeanFromPageContext(pageContext, arg0Name, null); 531 } 532 lc_args[0] = lc_arg0; 533 panel.doPrintTitle(out_buffer, LayoutUtils.getLabel(pageContext, getBundle(), title, lc_args, false)); 534 535 panel.doStartPanel(out_buffer, align,width); 536 } 537 538 539 546 public boolean isCurrentBeanSelected() throws JspException { 547 if (selectName!=null) { 548 Object lc_selectedValue = null; 549 if ("checkbox".equalsIgnoreCase(selectType)) { 550 if (selectId==null) { 551 lc_selectedValue = LayoutUtils.getBeanFromPageContext(pageContext, Constants.BEAN_KEY, selectName + "[" + (index-1) +"]"); 552 } else { 553 lc_selectedValue = LayoutUtils.getBeanFromPageContext(pageContext, Constants.BEAN_KEY, selectName + "(" + LayoutUtils.getProperty(bean, selectId) +")"); 554 } 555 } else { 556 lc_selectedValue = LayoutUtils.getBeanFromPageContext(pageContext, Constants.BEAN_KEY, selectName); 557 } 558 if (lc_selectedValue!=null && lc_selectedValue.equals(LayoutUtils.getProperty(bean, selectProperty))) { 559 return true; 560 } 561 } 562 return false; 563 } 564 public Object processStaticCodeIncludeEvent(StaticCodeIncludeLayoutEvent in_event) throws JspException { 565 String lc_codeToPrint = (String ) in_event.sendToParent(this); 566 staticCode += lc_codeToPrint; 567 return ""; 568 } 569 protected void renderStaticCode(StringBuffer out_buffer) { 570 if (staticCode.length()>0) { 571 out_buffer.append(staticCode); 572 staticCode = ""; 573 } 574 } 575 } 576 | Popular Tags |