KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > displaytag > tags > ColumnTag


1 /**
2  * Licensed under the Artistic License; you may not use this file
3  * except in compliance with the License.
4  * You may obtain a copy of the License at
5  *
6  * http://displaytag.sourceforge.net/license.html
7  *
8  * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
9  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11  */

12 package org.displaytag.tags;
13
14 import java.text.Collator JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.Comparator JavaDoc;
17 import java.util.List JavaDoc;
18
19 import javax.servlet.http.HttpServletRequest JavaDoc;
20 import javax.servlet.http.HttpServletResponse JavaDoc;
21 import javax.servlet.jsp.JspException JavaDoc;
22 import javax.servlet.jsp.tagext.BodyTagSupport JavaDoc;
23
24 import org.apache.commons.lang.StringUtils;
25 import org.apache.commons.lang.builder.ToStringBuilder;
26 import org.apache.commons.lang.builder.ToStringStyle;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.displaytag.decorator.AutolinkColumnDecorator;
30 import org.displaytag.decorator.DisplaytagColumnDecorator;
31 import org.displaytag.decorator.EscapeXmlColumnDecorator;
32 import org.displaytag.decorator.MessageFormatColumnDecorator;
33 import org.displaytag.exception.DecoratorInstantiationException;
34 import org.displaytag.exception.InvalidTagAttributeValueException;
35 import org.displaytag.exception.ObjectLookupException;
36 import org.displaytag.exception.TagStructureException;
37 import org.displaytag.model.Cell;
38 import org.displaytag.model.DefaultComparator;
39 import org.displaytag.model.HeaderCell;
40 import org.displaytag.properties.MediaTypeEnum;
41 import org.displaytag.properties.SortOrderEnum;
42 import org.displaytag.util.DefaultHref;
43 import org.displaytag.util.Href;
44 import org.displaytag.util.HtmlAttributeMap;
45 import org.displaytag.util.MediaUtil;
46 import org.displaytag.util.MultipleHtmlAttribute;
47 import org.displaytag.util.TagConstants;
48
49
50 /**
51  * <p>
52  * This tag works hand in hand with the TableTag to display a list of objects. This describes a column of data in the
53  * TableTag. There can be any number of columns that make up the list.
54  * </p>
55  * <p>
56  * This tag does no work itself, it is simply a container of information. The TableTag does all the work based on the
57  * information provided in the attributes of this tag.
58  * <p>
59  * @author mraible
60  * @author Fabrizio Giustina
61  * @version $Revision: 1008 $ ($Author: fgiust $)
62  */

63 public class ColumnTag extends BodyTagSupport JavaDoc implements MediaUtil.SupportsMedia
64 {
65
66     /**
67      * D1597A17A6.
68      */

69     private static final long serialVersionUID = 899149338534L;
70
71     /**
72      * logger.
73      */

74     private static Log log = LogFactory.getLog(ColumnTag.class);
75
76     /**
77      * html pass-through attributes for cells.
78      */

79     private HtmlAttributeMap attributeMap = new HtmlAttributeMap();
80
81     /**
82      * html pass-through attributes for cell headers.
83      */

84     private HtmlAttributeMap headerAttributeMap = new HtmlAttributeMap();
85
86     /**
87      * the property method that is called to retrieve the information to be displayed in this column. This method is
88      * called on the current object in the iteration for the given row. The property format is in typical struts format
89      * for properties (required)
90      */

91     private String JavaDoc property;
92
93     /**
94      * the title displayed for this column. if this is omitted then the property name is used for the title of the
95      * column (optional).
96      */

97     private String JavaDoc title;
98
99     /**
100      * by default, null values don't appear in the list, by setting viewNulls to 'true', then null values will appear as
101      * "null" in the list (mostly useful for debugging) (optional).
102      */

103     private boolean nulls;
104
105     /**
106      * is the column sortable?
107      */

108     private boolean sortable;
109
110     /**
111      * Name given to the server when sorting this column.
112      */

113     private String JavaDoc sortName;
114
115     /**
116      * Defalt sort order for this column.
117      */

118     private SortOrderEnum defaultorder;
119
120     /**
121      * The comparator to use when sorting this column.
122      */

123     private Comparator JavaDoc comparator;
124
125     /**
126      * if set to true, then any email addresses and URLs found in the content of the column are automatically converted
127      * into a hypertext link.
128      */

129     private boolean autolink;
130
131     /**
132      * Automatically escape column content for html and xml media.
133      */

134     private boolean escapeXml;
135
136     /**
137      * A MessageFormat patter that will be used to decorate objects in the column. Can be used as a "shortcut" for
138      * simple column decorations.
139      */

140     private String JavaDoc format;
141
142     /**
143      * the grouping level (starting at 1 and incrementing) of this column (indicates if successive contain the same
144      * values, then they should not be displayed). The level indicates that if a lower level no longer matches, then the
145      * matching for this higher level should start over as well. If this attribute is not included, then no grouping is
146      * performed. (optional)
147      */

148     private int group = -1;
149
150     /**
151      * if this attribute is provided, then the data that is shown for this column is wrapped inside a &lt;a href&gt; tag
152      * with the url provided through this attribute. Typically you would use this attribute along with one of the
153      * struts-like param attributes below to create a dynamic link so that each row creates a different URL based on the
154      * data that is being viewed. (optional)
155      */

156     private Href href;
157
158     /**
159      * The name of the request parameter that will be dynamically added to the generated href URL. The corresponding
160      * value is defined by the paramProperty and (optional) paramName attributes, optionally scoped by the paramScope
161      * attribute. (optional)
162      */

163     private String JavaDoc paramId;
164
165     /**
166      * The name of a JSP bean that is a String containing the value for the request parameter named by paramId (if
167      * paramProperty is not specified), or a JSP bean whose property getter is called to return a String (if
168      * paramProperty is specified). The JSP bean is constrained to the bean scope specified by the paramScope property,
169      * if it is specified. If paramName is omitted, then it is assumed that the current object being iterated on is the
170      * target bean. (optional)
171      */

172     private String JavaDoc paramName;
173
174     /**
175      * The name of a property of the bean specified by the paramName attribute (or the current object being iterated on
176      * if paramName is not provided), whose return value must be a String containing the value of the request parameter
177      * (named by the paramId attribute) that will be dynamically added to this href URL. (optional)
178      * @deprecated use Expressions in paramName
179      */

180     private String JavaDoc paramProperty;
181
182     /**
183      * The scope within which to search for the bean specified by the paramName attribute. If not specified, all scopes
184      * are searched. If paramName is not provided, then the current object being iterated on is assumed to be the target
185      * bean. (optional)
186      * @deprecated use Expressions in paramName
187      */

188     private String JavaDoc paramScope;
189
190     /**
191      * If this attribute is provided, then the column's displayed is limited to this number of characters. An elipse
192      * (...) is appended to the end if this column is linked, and the user can mouseover the elipse to get the full
193      * text. (optional)
194      */

195     private int maxLength;
196
197     /**
198      * If this attribute is provided, then the column's displayed is limited to this number of words. An elipse (...) is
199      * appended to the end if this column is linked, and the user can mouseover the elipse to get the full text.
200      * (optional)
201      */

202     private int maxWords;
203
204     /**
205      * a class that should be used to "decorate" the underlying object being displayed. If a decorator is specified for
206      * the entire table, then this decorator will decorate that decorator. (optional)
207      */

208     private String JavaDoc decorator;
209
210     /**
211      * is the column already sorted?
212      */

213     private boolean alreadySorted;
214
215     /**
216      * The media supported attribute.
217      */

218     private List JavaDoc supportedMedia;
219
220     /**
221      * Property in a resource bundle to be used as the title for the column.
222      */

223     private String JavaDoc titleKey;
224
225     /**
226      * The name of the bean property if a decorator is used and sorting need to be still on on the property itself.
227      * Useful for displaying data with links but sorting on original value.
228      */

229     private String JavaDoc sortProperty;
230
231     /**
232      * Should the value of the column be summed? Requires that the value of the column be convertible to a Number.
233      */

234     private boolean totaled;
235
236     /**
237      * Static value for this cell, equivalent to column body.
238      */

239     private Object JavaDoc value;
240
241     /**
242      * Setter for totals.
243      * @param totals the value
244      */

245     public void setTotal(boolean totals)
246     {
247         this.totaled = totals;
248     }
249
250     /**
251      * setter for the "property" tag attribute.
252      * @param value attribute value
253      */

254     public void setProperty(String JavaDoc value)
255     {
256         this.property = value;
257     }
258
259     /**
260      * setter for the "value" tag attribute.
261      * @param value attribute value
262      */

263     public void setValue(Object JavaDoc value)
264     {
265         this.value = value;
266     }
267
268     /**
269      * Set the comparator, classname or object.
270      * @param comparatorObj the comparator, classname or object
271      */

272     public void setComparator(Object JavaDoc comparatorObj)
273     {
274         // @todo don't do this! Setters should remains simple setters and any evaluation should be done in doEndTag()!
275
if (comparatorObj instanceof Comparator JavaDoc)
276         {
277             this.comparator = (Comparator JavaDoc) comparatorObj;
278         }
279         else if (comparatorObj instanceof String JavaDoc)
280         {
281             String JavaDoc comparatorClassname = (String JavaDoc) comparatorObj;
282             Class JavaDoc compClass;
283             try
284             {
285                 compClass = Thread.currentThread().getContextClassLoader().loadClass(comparatorClassname);
286             }
287             catch (ClassNotFoundException JavaDoc e)
288             {
289                 throw new RuntimeException JavaDoc("InstantiationException setting column comparator as "
290                     + comparatorClassname
291                     + ": "
292                     + e.getMessage(), e);
293             }
294             try
295             {
296                 this.comparator = (Comparator JavaDoc) compClass.newInstance();
297             }
298             catch (InstantiationException JavaDoc e)
299             {
300                 throw new RuntimeException JavaDoc("InstantiationException setting column comparator as "
301                     + comparatorClassname
302                     + ": "
303                     + e.getMessage(), e);
304             }
305             catch (IllegalAccessException JavaDoc e)
306             {
307                 throw new RuntimeException JavaDoc("IllegalAccessException setting column comparator as "
308                     + comparatorClassname
309                     + ": "
310                     + e.getMessage(), e);
311             }
312         }
313         else
314         {
315             throw new IllegalArgumentException JavaDoc("Value for comparator: "
316                 + comparatorObj
317                 + " of type "
318                 + comparatorObj.getClass().getName());
319         }
320     }
321
322     /**
323      * setter for the "title" tag attribute.
324      * @param value attribute value
325      */

326     public void setTitle(String JavaDoc value)
327     {
328         this.title = value;
329     }
330
331     /**
332      * setter for the "format" tag attribute.
333      * @param value attribute value
334      */

335     public void setFormat(String JavaDoc value)
336     {
337         this.format = value;
338     }
339
340     /**
341      * setter for the "nulls" tag attribute.
342      * @param value attribute value
343      */

344     public void setNulls(boolean value)
345     {
346         this.nulls = value;
347     }
348
349     /**
350      * setter for the "sortable" tag attribute.
351      * @param value attribute value
352      */

353     public void setSortable(boolean value)
354     {
355         this.sortable = value;
356     }
357
358     /**
359      * setter for the "autolink" tag attribute.
360      * @param value attribute value
361      */

362     public void setAutolink(boolean value)
363     {
364         this.autolink = value;
365     }
366
367     /**
368      * setter for the "escapeXml" tag attribute.
369      * @param value attribute value
370      */

371     public void setEscapeXml(boolean value)
372     {
373         this.escapeXml = value;
374     }
375
376     /**
377      * setter for the "group" tag attribute.
378      * @param value attribute value
379      */

380     public void setGroup(int value)
381     {
382         this.group = value;
383     }
384
385     /**
386      * setter for the "titleKey" tag attribute.
387      * @param value property name
388      */

389     public void setTitleKey(String JavaDoc value)
390     {
391         this.titleKey = value;
392     }
393
394     /**
395      * setter for the "href" tag attribute.
396      * @param value attribute value
397      */

398     public void setHref(String JavaDoc value)
399     {
400         // call encodeURL to preserve session id when cookies are disabled
401
String JavaDoc encodedHref = ((HttpServletResponse JavaDoc) this.pageContext.getResponse()).encodeURL(StringUtils
402             .defaultString(value));
403         this.href = new DefaultHref(encodedHref);
404     }
405
406     /**
407      * setter for the "url" tag attribute. This has the same meaning of href, but prepends the context path to the given
408      * URI.
409      * @param value attribute value
410      */

411     public void setUrl(String JavaDoc value)
412     {
413         HttpServletRequest JavaDoc req = (HttpServletRequest JavaDoc) pageContext.getRequest();
414         // call encodeURL to preserve session id when cookies are disabled
415
String JavaDoc encodedHref = ((HttpServletResponse JavaDoc) this.pageContext.getResponse()).encodeURL(StringUtils
416             .defaultString(req.getContextPath() + value));
417         this.href = new DefaultHref(encodedHref);
418     }
419
420     /**
421      * setter for the "paramId" tag attribute.
422      * @param value attribute value
423      */

424     public void setParamId(String JavaDoc value)
425     {
426         this.paramId = value;
427     }
428
429     /**
430      * setter for the "paramName" tag attribute.
431      * @param value attribute value
432      */

433     public void setParamName(String JavaDoc value)
434     {
435         this.paramName = value;
436     }
437
438     /**
439      * setter for the "paramProperty" tag attribute.
440      * @param value attribute value
441      */

442     public void setParamProperty(String JavaDoc value)
443     {
444         this.paramProperty = value;
445     }
446
447     /**
448      * setter for the "paramScope" tag attribute.
449      * @param value attribute value
450      */

451     public void setParamScope(String JavaDoc value)
452     {
453         this.paramScope = value;
454     }
455
456     /**
457      * setter for the "scope" tag attribute.
458      * @param value attribute value
459      */

460     public void setScope(String JavaDoc value)
461     {
462         this.attributeMap.put(TagConstants.ATTRIBUTE_SCOPE, value);
463     }
464
465     /**
466      * setter for the "headerScope" tag attribute.
467      * @param value attribute value
468      */

469     public void setHeaderScope(String JavaDoc value)
470     {
471         this.headerAttributeMap.put(TagConstants.ATTRIBUTE_SCOPE, value);
472     }
473
474     /**
475      * setter for the "maxLength" tag attribute.
476      * @param value attribute value
477      */

478     public void setMaxLength(int value)
479     {
480         this.maxLength = value;
481     }
482
483     /**
484      * setter for the "maxWords" tag attribute.
485      * @param value attribute value
486      */

487     public void setMaxWords(int value)
488     {
489         this.maxWords = value;
490     }
491
492     /**
493      * setter for the "style" tag attribute.
494      * @param value attribute value
495      */

496     public void setStyle(String JavaDoc value)
497     {
498         this.attributeMap.put(TagConstants.ATTRIBUTE_STYLE, value);
499     }
500
501     /**
502      * setter for the "class" tag attribute.
503      * @param value attribute value
504      */

505     public void setClass(String JavaDoc value)
506     {
507         this.attributeMap.put(TagConstants.ATTRIBUTE_CLASS, new MultipleHtmlAttribute(value));
508     }
509
510     /**
511      * setter for the "headerClass" tag attribute.
512      * @param value attribute value
513      */

514     public void setHeaderClass(String JavaDoc value)
515     {
516         this.headerAttributeMap.put(TagConstants.ATTRIBUTE_CLASS, new MultipleHtmlAttribute(value));
517     }
518
519     /**
520      * setter for the "decorator" tag attribute.
521      * @param value attribute value
522      */

523     public void setDecorator(String JavaDoc value)
524     {
525         this.decorator = value;
526     }
527
528     /**
529      * setter for the "sortProperty" tag attribute.
530      * @param value attribute value
531      */

532     public void setSortProperty(String JavaDoc value)
533     {
534         this.sortProperty = value;
535     }
536
537     /**
538      * Looks up the parent table tag.
539      * @return a table tag instance.
540      */

541     private TableTag getTableTag()
542     {
543         return (TableTag) findAncestorWithClass(this, TableTag.class);
544     }
545
546     /**
547      * Tag setter.
548      * @param media the space delimited list of supported types
549      */

550     public void setMedia(String JavaDoc media)
551     {
552         MediaUtil.setMedia(this, media);
553     }
554
555     /**
556      * @see org.displaytag.util.MediaUtil.SupportsMedia#setSupportedMedia(java.util.List)
557      */

558     public void setSupportedMedia(List JavaDoc media)
559     {
560         this.supportedMedia = media;
561     }
562
563     /**
564      * @see org.displaytag.util.MediaUtil.SupportsMedia#getSupportedMedia()
565      */

566     public List JavaDoc getSupportedMedia()
567     {
568         return this.supportedMedia;
569     }
570
571     /**
572      * sets the name given to the server when sorting this column
573      * @param sortName name given to the server to sort this column
574      */

575     public void setSortName(String JavaDoc sortName)
576     {
577         this.sortName = sortName;
578     }
579
580     /**
581      * sets the sorting order for the sorted column.
582      * @param value "ascending" or "descending"
583      * @throws InvalidTagAttributeValueException if value is not one of "ascending" or "descending"
584      */

585     public void setDefaultorder(String JavaDoc value) throws InvalidTagAttributeValueException
586     {
587         this.defaultorder = SortOrderEnum.fromName(value);
588         if (this.defaultorder == null)
589         {
590             throw new InvalidTagAttributeValueException(getClass(), "defaultorder", value); //$NON-NLS-1$
591
}
592     }
593
594     /**
595      * Passes attribute information up to the parent TableTag.
596      * <p>
597      * When we hit the end of the tag, we simply let our parent (which better be a TableTag) know what the user wants to
598      * do with this column. We do that by simple registering this tag with the parent. This tag's only job is to hold
599      * the configuration information to describe this particular column. The TableTag does all the work.
600      * </p>
601      * @return int
602      * @throws JspException if this tag is being used outside of a &lt;display:list...&gt; tag.
603      * @see javax.servlet.jsp.tagext.Tag#doEndTag()
604      */

605     public int doEndTag() throws JspException JavaDoc
606     {
607         TableTag tableTag = getTableTag();
608
609         MediaTypeEnum currentMediaType = (MediaTypeEnum) this.pageContext.findAttribute(TableTag.PAGE_ATTRIBUTE_MEDIA);
610         if (currentMediaType != null && !MediaUtil.availableForMedia(this, currentMediaType))
611         {
612             if (log.isDebugEnabled())
613             {
614                 log.debug("skipping column body, currentMediaType=" + currentMediaType);
615             }
616             return SKIP_BODY;
617         }
618
619         // add column header only once
620
if (tableTag.isFirstIteration())
621         {
622             addHeaderToTable(tableTag);
623         }
624
625         if (!tableTag.isIncludedRow())
626         {
627             return super.doEndTag();
628         }
629
630         Cell cell = null;
631         if (this.property == null && this.value != null)
632         {
633             cell = new Cell(value);
634         }
635         else if (this.property == null && this.bodyContent != null)
636         {
637             cell = new Cell(this.bodyContent.getString());
638         }
639
640         Object JavaDoc rowStyle = this.attributeMap.get(TagConstants.ATTRIBUTE_STYLE);
641         Object JavaDoc rowClass = this.attributeMap.get(TagConstants.ATTRIBUTE_CLASS);
642         if (rowStyle != null || rowClass != null)
643         {
644             HtmlAttributeMap perRowValues = new HtmlAttributeMap();
645             if (rowStyle != null)
646             {
647                 perRowValues.put(TagConstants.ATTRIBUTE_STYLE, rowStyle);
648             }
649             if (rowClass != null)
650             {
651                 perRowValues.put(TagConstants.ATTRIBUTE_CLASS, rowClass);
652             }
653             if (cell == null)
654             {
655                 cell = new Cell(null);
656             }
657             cell.setPerRowAttributes(perRowValues);
658         }
659
660         tableTag.addCell(cell != null ? cell : Cell.EMPTY_CELL);
661
662         // cleanup non-attribute variables
663
this.alreadySorted = false;
664
665         return super.doEndTag();
666     }
667
668     /**
669      * Adds the current header to the table model calling addColumn in the parent table tag. This method should be
670      * called only at first iteration.
671      * @param tableTag parent table tag
672      * @throws DecoratorInstantiationException for error during column decorator instantiation
673      * @throws ObjectLookupException for errors in looking up values
674      */

675     private void addHeaderToTable(TableTag tableTag) throws DecoratorInstantiationException, ObjectLookupException
676     {
677         // don't modify "title" directly
678
String JavaDoc evalTitle = this.title;
679
680         // title has precedence over titleKey
681
if (evalTitle == null && (this.titleKey != null || this.property != null))
682         {
683             // handle title i18n
684
evalTitle = tableTag.getProperties().geResourceProvider().getResource(
685                 this.titleKey,
686                 this.property,
687                 tableTag,
688                 this.pageContext);
689         }
690
691         HeaderCell headerCell = new HeaderCell();
692         headerCell.setHeaderAttributes((HtmlAttributeMap) this.headerAttributeMap.clone());
693         headerCell.setHtmlAttributes((HtmlAttributeMap) this.attributeMap.clone());
694         headerCell.setTitle(evalTitle);
695         headerCell.setSortable(this.sortable);
696
697         List JavaDoc decorators = new ArrayList JavaDoc();
698
699         // handle multiple chained decorators, whitespace separated
700
if (StringUtils.isNotEmpty(this.decorator))
701         {
702             String JavaDoc[] decoratorNames = StringUtils.split(this.decorator);
703             for (int j = 0; j < decoratorNames.length; j++)
704             {
705                 decorators.add(tableTag.getProperties().getDecoratorFactoryInstance().loadColumnDecorator(
706                     this.pageContext,
707                     decoratorNames[j]));
708             }
709         }
710
711         // "special" decorators
712
if (this.escapeXml)
713         {
714             decorators.add(EscapeXmlColumnDecorator.INSTANCE);
715         }
716         if (this.autolink)
717         {
718             decorators.add(AutolinkColumnDecorator.INSTANCE);
719         }
720         if (StringUtils.isNotBlank(this.format))
721         {
722             decorators.add(new MessageFormatColumnDecorator(this.format, tableTag.getProperties().getLocale()));
723         }
724
725         headerCell.setColumnDecorators((DisplaytagColumnDecorator[]) decorators
726             .toArray(new DisplaytagColumnDecorator[decorators.size()]));
727
728         headerCell.setBeanPropertyName(this.property);
729         headerCell.setShowNulls(this.nulls);
730         headerCell.setMaxLength(this.maxLength);
731         headerCell.setMaxWords(this.maxWords);
732         headerCell.setGroup(this.group);
733         headerCell.setSortProperty(this.sortProperty);
734         headerCell.setTotaled(this.totaled);
735
736         Comparator JavaDoc headerComparator = (comparator != null) ? comparator : new DefaultComparator(Collator
737             .getInstance(tableTag.getProperties().getLocale()));
738
739         headerCell.setComparator(headerComparator);
740         headerCell.setDefaultSortOrder(this.defaultorder);
741         headerCell.setSortName(this.sortName);
742
743         // href and parameter, create link
744
if (this.href != null)
745         {
746             Href colHref;
747
748             // empty base url, use href with parameters from parent table
749
if (StringUtils.isEmpty(this.href.getBaseUrl()))
750             {
751                 colHref = (Href) tableTag.getBaseHref().clone();
752             }
753             else
754             {
755                 colHref = (Href) this.href.clone();
756             }
757
758             if (this.paramId != null)
759             {
760                 // parameter value is in a different object than the iterated one
761
if (this.paramName != null || this.paramScope != null)
762                 {
763                     // create a complete string for compatibility with previous version before expression evaluation.
764
// this approach is optimized for new expressions, not for previous property/scope parameters
765
StringBuffer JavaDoc expression = new StringBuffer JavaDoc();
766
767                     // append scope
768
if (StringUtils.isNotBlank(this.paramScope))
769                     {
770                         expression.append(this.paramScope).append("Scope.");
771                     }
772
773                     // base bean name
774
if (this.paramId != null)
775                     {
776                         expression.append(this.paramName);
777                     }
778                     else
779                     {
780                         expression.append(tableTag.getName());
781                     }
782
783                     // append property
784
if (StringUtils.isNotBlank(this.paramProperty))
785                     {
786                         expression.append('.').append(this.paramProperty);
787                     }
788
789                     // evaluate expression.
790
// note the value is fixed, not based on any object created during iteration
791
// this is here for compatibility with the old version mainly
792
Object JavaDoc paramValue = tableTag.evaluateExpression(expression.toString());
793
794                     // add parameter
795
colHref.addParameter(this.paramId, paramValue);
796                 }
797                 else
798                 {
799                     // set id
800
headerCell.setParamName(this.paramId);
801
802                     // set property
803
headerCell.setParamProperty(this.paramProperty);
804                 }
805             }
806
807             // sets the base href
808
headerCell.setHref(colHref);
809
810         }
811
812         tableTag.addColumn(headerCell);
813
814         if (log.isDebugEnabled())
815         {
816             log.debug("columnTag.addHeaderToTable() :: first iteration - adding header " + headerCell);
817         }
818     }
819
820     /**
821      * @see javax.servlet.jsp.tagext.Tag#release()
822      */

823     public void release()
824     {
825         super.release();
826         this.attributeMap.clear();
827         this.autolink = false;
828         this.decorator = null;
829         this.group = -1;
830         this.headerAttributeMap.clear();
831         this.href = null;
832         this.maxLength = 0;
833         this.maxWords = 0;
834         this.nulls = false;
835         this.paramId = null;
836         this.paramName = null;
837         this.paramProperty = null;
838         this.paramScope = null;
839         this.property = null;
840         this.sortable = false;
841         this.sortName = null;
842         this.supportedMedia = null;
843         this.title = null;
844         this.titleKey = null;
845         this.sortProperty = null;
846         this.comparator = null;
847         this.defaultorder = null;
848         this.escapeXml = false;
849         this.format = null;
850         this.value = null;
851     }
852
853     /**
854      * @see javax.servlet.jsp.tagext.Tag#doStartTag()
855      */

856     public int doStartTag() throws JspException JavaDoc
857     {
858         TableTag tableTag = getTableTag();
859         if (tableTag == null)
860         {
861             throw new TagStructureException(getClass(), "column", "table");
862         }
863
864         // If the list is empty, do not execute the body; may result in NPE
865
if (tableTag.isEmpty() || !tableTag.isIncludedRow())
866         {
867             return SKIP_BODY;
868         }
869
870         MediaTypeEnum currentMediaType = (MediaTypeEnum) this.pageContext.findAttribute(TableTag.PAGE_ATTRIBUTE_MEDIA);
871         if (!MediaUtil.availableForMedia(this, currentMediaType))
872         {
873             return SKIP_BODY;
874         }
875
876         return super.doStartTag();
877     }
878
879     /**
880      * @see java.lang.Object#toString()
881      */

882     public String JavaDoc toString()
883     {
884         return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) //
885
.append("bodyContent", this.bodyContent) //$NON-NLS-1$
886
.append("group", this.group) //$NON-NLS-1$
887
.append("maxLength", this.maxLength) //$NON-NLS-1$
888
.append("decorator", this.decorator) //$NON-NLS-1$
889
.append("href", this.href) //$NON-NLS-1$
890
.append("title", this.title) //$NON-NLS-1$
891
.append("paramScope", this.paramScope) //$NON-NLS-1$
892
.append("property", this.property) //$NON-NLS-1$
893
.append("paramProperty", this.paramProperty) //$NON-NLS-1$
894
.append("headerAttributeMap", this.headerAttributeMap) //$NON-NLS-1$
895
.append("paramName", this.paramName) //$NON-NLS-1$
896
.append("autolink", this.autolink) //$NON-NLS-1$
897
.append("format", this.format) //$NON-NLS-1$
898
.append("nulls", this.nulls) //$NON-NLS-1$
899
.append("maxWords", this.maxWords) //$NON-NLS-1$
900
.append("attributeMap", this.attributeMap) //$NON-NLS-1$
901
.append("sortable", this.sortable) //$NON-NLS-1$
902
.append("paramId", this.paramId) //$NON-NLS-1$
903
.append("alreadySorted", this.alreadySorted) //$NON-NLS-1$
904
.append("sortProperty", this.sortProperty) //$NON-NLS-1$
905
.append("defaultSortOrder", this.defaultorder) //$NON-NLS-1$
906
.toString();
907     }
908
909 }
Popular Tags