View Javadoc

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.model;
13  
14  import java.util.Comparator;
15  
16  import org.apache.commons.beanutils.Converter;
17  import org.apache.commons.lang.StringUtils;
18  import org.apache.commons.lang.builder.ToStringBuilder;
19  import org.apache.commons.lang.builder.ToStringStyle;
20  import org.displaytag.decorator.DisplaytagColumnDecorator;
21  import org.displaytag.exception.DecoratorException;
22  import org.displaytag.exception.ObjectLookupException;
23  import org.displaytag.properties.SortOrderEnum;
24  import org.displaytag.util.Href;
25  import org.displaytag.util.HtmlAttributeMap;
26  import org.displaytag.util.HtmlTagUtil;
27  import org.displaytag.util.MultipleHtmlAttribute;
28  import org.displaytag.util.TagConstants;
29  
30  
31  /**
32   * DataObject representing the column header. The header cell contains all the properties common to cells in the same
33   * column.
34   * @author Fabrizio Giustina
35   * @version $Revision: 1087 $ ($Author: rapruitt $)
36   */
37  public class HeaderCell
38  {
39  
40      /**
41       * Map containing the html tag attributes for cells (td).
42       */
43      private HtmlAttributeMap htmlAttributes;
44  
45      /**
46       * Map containing the html tag attributes for header cells (td).
47       */
48      private HtmlAttributeMap headerAttributes;
49  
50      /**
51       * base href for creating dinamic links.
52       */
53      private Href href;
54  
55      /**
56       * param name used in adding a link.
57       */
58      private String paramName;
59  
60      /**
61       * property of the object where to get the param value from.
62       */
63      private String paramProperty;
64  
65      /**
66       * column title.
67       */
68      private String title;
69  
70      /**
71       * is the column sortable?
72       */
73      private boolean sortable;
74  
75      /**
76       * Name given to the server when sorting this column
77       */
78      private String sortName;
79  
80      /**
81       * ColumnDecorators.
82       */
83      private DisplaytagColumnDecorator[] columnDecorators;
84  
85      /**
86       * column number.
87       */
88      private int columnNumber;
89  
90      /**
91       * is the column sorted?
92       */
93      private boolean alreadySorted;
94  
95      /**
96       * property name to look up in the bean.
97       */
98      private String beanPropertyName;
99  
100     /**
101      * show null values?
102      */
103     private boolean showNulls;
104 
105     /**
106      * max length of cell content.
107      */
108     private int maxLength;
109 
110     /**
111      * max number of words for cell content.
112      */
113     private int maxWords;
114 
115     /**
116      * group the column?
117      */
118     private int group;
119 
120     /**
121      * Name of the non-decorated property used during sorting.
122      */
123     private String sortPropertyName;
124 
125     /**
126      * Should we be attempting to tabulate the totals?
127      */
128     private boolean totaled;
129 
130     /**
131      * Defalt sort order for this column.
132      */
133     private SortOrderEnum defaultSortOrder;
134 
135     /**
136      * The running total for the column.
137      */
138     private double total;
139 
140     /**
141      * Use this comparator for sorting.
142      */
143     private Comparator comparator;
144 
145     /**
146      * getter for the grouping index.
147      * @return 0 if the column is not grouped or the grouping order
148      */
149     public int getGroup()
150     {
151         return this.group;
152     }
153 
154     /**
155      * setter for the grouping index.
156      * @param groupingOrder int grouping order (>0)
157      */
158     public void setGroup(int groupingOrder)
159     {
160         this.group = groupingOrder;
161     }
162 
163     /**
164      * getter for the max number of characters to display in the column.
165      * @return int number of characters to display in the column
166      */
167     public int getMaxLength()
168     {
169         return this.maxLength;
170     }
171 
172     /**
173      * setter for the max number of characters to display in the column.
174      * @param numOfChars number of characters to display in the column
175      */
176     public void setMaxLength(int numOfChars)
177     {
178         this.maxLength = numOfChars;
179     }
180 
181     /**
182      * getter for the max number of words to display in the column.
183      * @return int number of words to display in the column
184      */
185     public int getMaxWords()
186     {
187         return this.maxWords;
188     }
189 
190     /**
191      * setter for the max number of words to display in the column.
192      * @param numOfWords number of words to display in the column
193      */
194     public void setMaxWords(int numOfWords)
195     {
196         this.maxWords = numOfWords;
197     }
198 
199     /**
200      * Should null be displayed?
201      * @return true null will be displayed in cell content
202      */
203     public boolean getShowNulls()
204     {
205         return this.showNulls;
206     }
207 
208     /**
209      * Enable or disable displaying of null values.
210      * @param outputNulls boolean true if null should be displayed
211      */
212     public void setShowNulls(boolean outputNulls)
213     {
214         this.showNulls = outputNulls;
215     }
216 
217     /**
218      * Getter for the name of the property to look up in the bean.
219      * @return String name of the property to look up in the bean
220      */
221     public String getBeanPropertyName()
222     {
223         return this.beanPropertyName;
224     }
225 
226     /**
227      * Setter for the name of the property to look up in the bean.
228      * @param propertyName - name of the property to look up in the bean
229      */
230     public void setBeanPropertyName(String propertyName)
231     {
232         this.beanPropertyName = propertyName;
233     }
234 
235     /**
236      * Is the column already sorted?
237      * @return true if the column already sorted
238      */
239     public boolean isAlreadySorted()
240     {
241         return this.alreadySorted;
242     }
243 
244     /**
245      * Setter for the sorted property (the column is actually sorted).
246      */
247     public void setAlreadySorted()
248     {
249         this.alreadySorted = true;
250     }
251 
252     /**
253      * Getter for the column number.
254      * @return int column number
255      */
256     public int getColumnNumber()
257     {
258         return this.columnNumber;
259     }
260 
261     /**
262      * Setter for the column number.
263      * @param number - int column number
264      */
265     public void setColumnNumber(int number)
266     {
267         this.columnNumber = number;
268     }
269 
270     /**
271      * Returns the columnDecorator object for this column.
272      * @return DisplaytagColumnDecorator
273      */
274     public DisplaytagColumnDecorator[] getColumnDecorators()
275     {
276         return this.columnDecorators != null ? this.columnDecorators : new DisplaytagColumnDecorator[0];
277     }
278 
279     /**
280      * Sets the columnDecorator object for this column.
281      * @param decorator - the DisplaytagColumnDecorator
282      */
283     public void setColumnDecorators(DisplaytagColumnDecorator[] decorator)
284     {
285         this.columnDecorators = decorator;
286     }
287 
288     /**
289      * Is the column sortable?
290      * @return true if the column is sortable
291      */
292     public boolean getSortable()
293     {
294         return this.sortable;
295     }
296 
297     /**
298      * is the column sortable?
299      * @param isSortable - true if the column can be sorted
300      */
301     public void setSortable(boolean isSortable)
302     {
303         this.sortable = isSortable;
304     }
305 
306     /**
307      * Get name given to server for sorting this column
308      * @return name given to server for sorting this column
309      */
310     public String getSortName()
311     {
312         return sortName;
313     }
314 
315     /**
316      * Set name given to server for sorting this column
317      * @param sortName name given to server for sorting this column
318      */
319     public void setSortName(String sortName)
320     {
321         this.sortName = sortName;
322     }
323 
324     /**
325      * Gets the column title.
326      * @return the column title. If no title is specified the capitalized bean property name is returned
327      */
328     public String getTitle()
329     {
330         if (this.title != null)
331         {
332             return this.title;
333         }
334         else if (this.beanPropertyName != null)
335         {
336             return StringUtils.capitalize(this.beanPropertyName);
337         }
338 
339         return TagConstants.EMPTY_STRING;
340     }
341 
342     /**
343      * Setter for the column title.
344      * @param value - the column title
345      */
346     public void setTitle(String value)
347     {
348         this.title = value;
349     }
350 
351     /**
352      * Returns the HtmlAttributeMap containg all the html attributes for the <strong>td </strong> tags.
353      * @return HtmlAttributeMap with td attributes
354      */
355     public HtmlAttributeMap getHtmlAttributes()
356     {
357         return this.htmlAttributes;
358     }
359 
360     /**
361      * Sets the HtmlAttributeMap containg all the html attributes for the <strong>td </strong> tags.
362      * @param attributes HtmlAttributeMap
363      */
364     public void setHtmlAttributes(HtmlAttributeMap attributes)
365     {
366         this.htmlAttributes = attributes;
367     }
368 
369     /**
370      * returns the HtmlAttributeMap containg all the html attributes for the <strong>th </strong> tag.
371      * @return HtmlAttributeMap with th attributes
372      */
373     public HtmlAttributeMap getHeaderAttributes()
374     {
375         return this.headerAttributes;
376     }
377 
378     /**
379      * Sets the HtmlAttributeMap containg all the html attributes for the <strong>th </strong> tag.
380      * @param attributes HtmlAttributeMap
381      */
382     public void setHeaderAttributes(HtmlAttributeMap attributes)
383     {
384         this.headerAttributes = attributes;
385     }
386 
387     /**
388      * Adds a css class to the html "class" attribute.
389      * @param cssClass String
390      */
391     public void addHeaderClass(String cssClass)
392     {
393         // null safe
394         if (StringUtils.isBlank(cssClass))
395         {
396             return;
397         }
398 
399         // if headerAttributes has not been set, instantiates a new map
400         if (headerAttributes == null)
401         {
402             headerAttributes = new HtmlAttributeMap();
403         }
404 
405         Object classAttributes = this.headerAttributes.get(TagConstants.ATTRIBUTE_CLASS);
406 
407         // handle multiple values
408         if (classAttributes == null)
409         {
410             this.headerAttributes.put(TagConstants.ATTRIBUTE_CLASS, new MultipleHtmlAttribute(cssClass));
411         }
412         else
413         {
414             ((MultipleHtmlAttribute) classAttributes).addAttributeValue(cssClass);
415         }
416     }
417 
418     /**
419      * return the open tag for a column header (th).
420      * @return String &lt;th&gt; tag with attributes
421      */
422     public String getHeaderOpenTag()
423     {
424         return HtmlTagUtil.createOpenTagString(TagConstants.TAGNAME_COLUMN_HEADER, this.headerAttributes);
425     }
426 
427     /**
428      * return the closing tag for a cell (td).
429      * @return String &lt;/td&gt;
430      */
431     public String getCloseTag()
432     {
433         return TagConstants.TAG_OPENCLOSING + TagConstants.TAGNAME_COLUMN + TagConstants.TAG_CLOSE;
434     }
435 
436     /**
437      * return the closing tag for a column header (th).
438      * @return String &lt;/th&gt;
439      */
440     public String getHeaderCloseTag()
441     {
442         return TagConstants.TAG_OPENCLOSING + TagConstants.TAGNAME_COLUMN_HEADER + TagConstants.TAG_CLOSE;
443     }
444 
445     /**
446      * Setter for the href to be used for dinamic links in cells.
447      * @param baseHref base href for links
448      */
449     public void setHref(Href baseHref)
450     {
451         this.href = baseHref;
452     }
453 
454     /**
455      * Getter for the href to be used for dinamic links in cells.
456      * @return Href base href for links
457      */
458     public Href getHref()
459     {
460         return this.href;
461     }
462 
463     /**
464      * Setter for the name of the param to add to links.
465      * @param name name of the param
466      */
467     public void setParamName(String name)
468     {
469         this.paramName = name;
470     }
471 
472     /**
473      * Getter for the name of the param to add to links.
474      * @return String name of the param
475      */
476     public String getParamName()
477     {
478         return this.paramName;
479     }
480 
481     /**
482      * Setter for the name of the property to look up in bean to get the param value for links.
483      * @param property name of the property to look up in bean to get the param value for links
484      */
485     public void setParamProperty(String property)
486     {
487         this.paramProperty = property;
488     }
489 
490     /**
491      * Getter for the name of the property to look up in bean to get the param value for links.
492      * @return String name of the property to look up in bean to get the param value for links
493      */
494     public String getParamProperty()
495     {
496         return this.paramProperty;
497     }
498 
499     /**
500      * Getter for the name of the property in the bean which will be used for sorting.
501      * @return String name of the property in the bean which will be used for sorting
502      */
503     public String getSortProperty()
504     {
505         return this.sortPropertyName;
506     }
507 
508     /**
509      * Setter for the name of the property in the bean which will be used for sorting.
510      * @param propertyName - name of the property in the bean which will be used for sorting
511      */
512     public void setSortProperty(String propertyName)
513     {
514         this.sortPropertyName = propertyName;
515     }
516 
517     /**
518      * Sets the default sort order for this column
519      * @return default order
520      */
521     public SortOrderEnum getDefaultSortOrder()
522     {
523         return this.defaultSortOrder;
524     }
525 
526     /**
527      * Gets the default sort order for this column
528      * @param order default order
529      */
530     public void setDefaultSortOrder(SortOrderEnum order)
531     {
532         this.defaultSortOrder = order;
533     }
534 
535     /**
536      * @see java.lang.Object#toString()
537      */
538     public String toString()
539     {
540         return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) //
541             .append("columnNumber", this.columnNumber) //$NON-NLS-1$
542             .append("title", this.title) //$NON-NLS-1$
543             .append("beanPropertyName", this.beanPropertyName) //$NON-NLS-1$
544             .toString();
545     }
546 
547     /**
548      * Set the column comparator.
549      * @param columnComparator the value
550      */
551     public void setComparator(Comparator columnComparator)
552     {
553         this.comparator = columnComparator;
554     }
555 
556     /**
557      * Get the comparator for sorting this column.
558      * @return the comparator
559      */
560     public Comparator getComparator()
561     {
562         return this.comparator;
563     }
564 
565     /**
566      * Will we be keeping a total for this column?
567      * @return true if we are totaling
568      */
569     public boolean isTotaled()
570     {
571         return totaled;
572     }
573 
574     /**
575      * Setter for totaled.
576      * @param isTotaled the value
577      */
578     public void setTotaled(boolean isTotaled)
579     {
580         this.totaled = isTotaled;
581     }
582 
583     /**
584      * Add the value of this parameter to the column total. The param will be converted to a number via a property
585      * Converter.
586      * @param value the value
587      * @see Converter#convert(Class, Object)
588      */
589     private void addToTotal(Object value)
590     {
591         if (value != null && value instanceof Number)
592         {
593             this.total = this.total + ((Number) value).doubleValue();
594         }
595     }
596 
597     /**
598      * Get the current total.
599      * @return the current total.
600      */
601     public double getTotal()
602     {
603         return this.total;
604     }
605 
606     /**
607      * Add a new cell to this column.
608      * @param column the value
609      */
610     public void addCell(Column column)
611     {
612         // Not actually going to hold a reference to the added cell - we just need access for the totals
613         if (this.totaled)
614         {
615             try
616             {
617                 Object val = column.getValue(false);
618                 addToTotal(val);
619             }
620             catch (ObjectLookupException e)
621             {
622                 throw new RuntimeException(e);
623             }
624             catch (DecoratorException e)
625             {
626                 throw new RuntimeException(e);
627             }
628         }
629     }
630 
631 }