View Javadoc

1   /***
2    *                                                                          
3    * This library is free software; you can redistribute it and/or modify it    
4    * under the terms of the GNU Lesser General Public License as published      
5    * by the Free Software Foundation; either version 2.1 of the License, or 
6    * (at your option) any later version.                                            
7    *                                                                            
8    * This library is distributed in the hope that it will be useful, but 
9    * WITHOUT ANY WARRANTY; with out even the implied warranty of 
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
11   * GNU Lesser General Public License for more details.                                                  
12   *                                                                           
13   * You should have received a copy of the GNU Lesser General Public License   
14   * along with this library;  if not, write to the Free Software Foundation,   
15   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.              
16   *                                                                            
17   * > http://www.gnu.org/copyleft/lesser.html                                  
18   * > http://www.opensource.org/licenses/lgpl-license.php
19   */
20  package net.mlw.vlh.web.tag;
21  
22  import java.util.List;
23  import java.util.Locale;
24  
25  import javax.servlet.http.HttpServletRequest;
26  import javax.servlet.jsp.JspException;
27  
28  import net.mlw.vlh.ValueListInfo;
29  import net.mlw.vlh.web.ValueListConfigBean;
30  import net.mlw.vlh.web.tag.support.ColumnInfo;
31  import net.mlw.vlh.web.tag.support.DisplayProvider;
32  import net.mlw.vlh.web.util.JspUtils;
33  
34  import org.apache.commons.beanutils.PropertyUtils;
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogFactory;
37  
38  /***
39   * This tag creates a column in a row, emphase wanted data 
40   * and format column with specific locale. If is it not specified,
41   * use spring LocaleResolver to obtain default locale.
42   * 
43   * @todo Document this tag.
44   * @author Matthew L. Wilson, Andrej Zachar
45   * @version $Revision: 1.23 $ $Date: 2006/01/06 10:53:54 $
46   */
47  //This class was refactored with using BaseColumnTag. Some methods and fields were pull up.
48  public class DefaultColumnTag extends BaseColumnTag
49  {
50  
51     private static final long serialVersionUID = -1160414311192942253L;
52  
53     /***
54      * Logger for this class
55      */
56     private static final Log LOGGER = LogFactory.getLog(DefaultColumnTag.class);
57  
58     /*** Supports column Grouping. **/
59     private String groupKey;
60  
61     private String sum;
62  
63     /*** Holder of default sort direction, null is not sortable. */
64     private Integer defaultSort;
65  
66     /*** The javabean property name of this column used to get data from list returned by adapter. */
67     private String property;
68  
69     /*** The property name to use to retrieve do for this columns in an adapter. */
70     private String adapterProperty = null;
71  
72     private String format;
73  
74     private String defaultValue;
75  
76     /*** The pattern to be emphasis displayed in the ordinary column cell. */
77     private String emphasisPattern = null;
78  
79     /*** Locale used in column */
80     private Locale locale = null;
81  
82     private List nestedColumnInfoList = null;
83  
84     /***
85      * @return Returns the adapterProperty. if it is null, return ordinary property.
86      */
87     public String getAdapterProperty()
88     {
89        return adapterProperty == null ? property : adapterProperty;
90     }
91  
92     /***
93      * @param sqlProperty The sql property name to use to retrieve do for this columns in adapter.
94      */
95     public void setAdapterProperty(String sqlProperty)
96     {
97        this.adapterProperty = sqlProperty;
98     }
99  
100    /***
101     * Initialization is called at the beginning of <code>doStart</code>.
102     * Subclasses have to call either <code>super.init()</code> or <code>super.doStart()</code>.
103     * @throws JspException
104     */
105    protected void init() throws JspException
106    {
107       if (bodyContent != null)
108       {
109          bodyContent.clearBody();
110       }
111    }
112 
113    /***
114     * @see javax.servlet.jsp.tagext.Tag#doStartTag()
115     */
116    public int doStartTag() throws JspException
117    {
118       init();
119       return super.doStartTag();
120    }
121 
122    /***
123     * @see javax.servlet.jsp.tagext.Tag#doEndTag()
124     */
125    public int doEndTag() throws JspException
126    {
127 
128       ValueListSpaceTag rootTag = (ValueListSpaceTag) JspUtils.getParent(this, ValueListSpaceTag.class);
129 
130       DefaultRowTag rowTag = (DefaultRowTag) JspUtils.getParent(this, DefaultRowTag.class);
131 
132       ValueListConfigBean config = rootTag.getConfig();
133 
134       appendClassCellAttribute(rowTag.getRowStyleClass());
135 
136       if (locale == null)
137       {
138          locale = config.getLocaleResolver().resolveLocale((HttpServletRequest) pageContext.getRequest());
139       }
140 
141       if (rowTag.getCurrentRowNumber() == 0) // if this is the 1st row == the one with cell headers
142       {
143 
144          String titleKey = getTitleKey();
145          String label = (titleKey == null) ? getTitle() : config.getMessageSource().getMessage(titleKey, null, titleKey, locale);
146 
147          ColumnInfo columnInfo = new ColumnInfo(config.getDisplayHelper().help(pageContext, label), getAdapterProperty(), defaultSort,
148                getAttributes());
149 
150          // Process toolTip if any
151          // toolTip or toolTipKey is set => get the string and put it into the ColumnInfo
152          String toolTipKey = getToolTipKey();
153          columnInfo.setToolTip((toolTipKey == null) ? getToolTip() : config.getMessageSource().getMessage(toolTipKey, null, toolTipKey,
154                locale));
155 
156          columnInfo.setNestedList(this.nestedColumnInfoList);
157 
158          rowTag.addColumnInfo(columnInfo);
159       }
160 
161       DisplayProvider displayProvider = rowTag.getDisplayProvider();
162 
163       StringBuffer sb = new StringBuffer(displayProvider.getCellPreProcess(getCellAttributes()));
164 
165       if (displayProvider.doesIncludeBodyContent() && bodyContent != null && bodyContent.getString() != null
166             && bodyContent.getString().trim().length() > 0)
167       {
168          sb.append(bodyContent.getString().trim());
169          bodyContent.clearBody();
170       }
171       else
172       {
173          if (property != null && rowTag.getBeanName() != null)
174          {
175             try
176             {
177                Object bean = pageContext.getAttribute(rowTag.getBeanName());
178                if (bean != null)
179                {
180                   Object value = null;
181                   try
182                   {
183                      value = PropertyUtils.getProperty(bean, property);
184                   }
185                   catch (Exception e)
186                   {
187                      //Do nothing, if you want to handle this exception, then
188                      // use a try catch in the body content.
189                      LOGGER.error("<vlh:column> Error getting property='" + property + "' from the iterated JavaBean name='"
190                            + rowTag.getBeanName() + "'\n The row's JavaBean was >>>" + bean
191                            + "<<<\n Check the syntax or the spelling of the column's property!");
192                   }
193 
194                   if (value != null)
195                   {
196                      if (sum != null && value instanceof Number)
197                      {
198                         double doubleValue = ((Number) value).doubleValue();
199                         Double sumValue = (Double) pageContext.getAttribute(sum);
200                         if (sumValue == null)
201                         {
202                            sumValue = new Double(doubleValue);
203                         }
204                         else
205                         {
206                            sumValue = new Double(sumValue.doubleValue() + doubleValue);
207                         }
208                         pageContext.setAttribute(sum, sumValue);
209                      }
210                      String formattedValue = JspUtils.format(value, format, locale);
211 
212                      if (groupKey == null
213                            || (config.getCellInterceptor() == null || !config.getCellInterceptor().isHidden(pageContext, groupKey,
214                                  property, formattedValue)))
215                      {
216                         sb.append(displayProvider.emphase(formattedValue, getEmphasisPattern(), getColumnStyleClass()));
217                      }
218 
219                   }
220                   else
221                   {
222                      if (LOGGER.isDebugEnabled())
223                      {
224                         LOGGER.debug("The property '" + property + "' of the iterated JavaBean '" + bean + "' is null!");
225                      }
226 
227                      Object nullValue = (defaultValue == null) ? config.getNullToken() : defaultValue;
228 
229                      if (groupKey == null
230                            || (config.getCellInterceptor() == null || !config.getCellInterceptor().isHidden(pageContext, groupKey,
231                                  property, nullValue)))
232                      {
233                         sb.append(nullValue);
234                      }
235                   }
236                }
237             }
238             catch (Exception e)
239             {
240                final String message = "DefaultColumnTag.doEndTag() - <vlh:column> error getting property: " + property + " from bean.";
241                LOGGER.error(message, e);
242                throw new JspException(message, e);
243             }
244          }
245       }
246 
247       sb.append(displayProvider.getCellPostProcess());
248       JspUtils.write(pageContext, sb.toString());
249 
250       release();
251 
252       return EVAL_PAGE;
253    }
254 
255    public String getColumnStyleClass() throws JspException
256    {
257 
258       ValueListSpaceTag rootTag = (ValueListSpaceTag) JspUtils.getParent(this, ValueListSpaceTag.class);
259 
260       ValueListConfigBean config = rootTag.getConfig();
261 
262       if (config == null)
263       {
264          throw new JspException("No config found on root tag");
265       }
266 
267       return config.getStylePrefix();
268    }
269 
270    /***
271     * Sets the defaultSort property.
272     * 
273     * @param value
274     *           Valid values are "asc" and "desc".
275     */
276    public void setSortable(String value)
277    {
278       if ("asc".equals(value))
279       {
280          defaultSort = ValueListInfo.ASCENDING;
281       }
282       else if ("desc".equals(value))
283       {
284          defaultSort = ValueListInfo.DESCENDING;
285       }
286    }
287 
288    /***
289     * @return Returns the property.
290     */
291    public String getProperty()
292    {
293       return this.property;
294    }
295 
296    /***
297     * Sets the javabean property name of this column
298     * used to get data from list returned by adapter.
299     * @param property
300     *           The javabean property name of this column.
301     */
302    public void setProperty(String property)
303    {
304       this.property = property;
305    }
306 
307    /***
308     * @return Returns the format.
309     */
310    public String getFormat()
311    {
312       return this.format;
313    }
314 
315    /***
316     * @param format
317     *           The format to set.
318     */
319    public void setFormat(String format)
320    {
321       this.format = format;
322    }
323 
324    /***
325     * @return Returns the sum.
326     */
327    public String getSum()
328    {
329       return this.sum;
330    }
331 
332    /***
333     * @param sum
334     *           The sum to set.
335     */
336    public void setSum(String sum)
337    {
338       this.sum = sum;
339    }
340 
341    /***
342     * @return Returns the defaultValue.
343     */
344    public String getDefault()
345    {
346       return this.defaultValue;
347    }
348 
349    /***
350     * @param defaultValue The defaultValue to set.
351     */
352    public void setDefault(String defaultValue)
353    {
354       this.defaultValue = defaultValue;
355    }
356 
357    /***
358     * @return Returns the emphasisPattern.
359     */
360    public String getEmphasisPattern()
361    {
362       return this.emphasisPattern;
363    }
364 
365    /***
366     * It is used to emphasis part of text part of content of the displayed
367     * table cell. if <i>emphasisPattern</i> is empty("") sets it to null.
368     * @param emphasisPattern The emphasisPattern to set.
369     */
370    public void setEmphasisPattern(String emphasisPattern)
371    {
372       this.emphasisPattern = (emphasisPattern == null || emphasisPattern.length() == 0) ? null : emphasisPattern;
373    }
374 
375    /***
376     * @param locale The locale to set for column.
377     */
378    public void setLocale(Locale locale)
379    {
380       this.locale = locale;
381    }
382 
383    /***
384     * @return Returns the groupKey.
385     */
386    public String getGroupKey()
387    {
388       return this.groupKey;
389    }
390 
391    /***
392     * @param groupKey The groupKey to set.
393     */
394    public void setGroupKey(String groupKey)
395    {
396       this.groupKey = groupKey;
397    }
398 
399    /***
400     * @return Returns the nestedColumnInfoList.
401     */
402    public List getNestedColumnInfoList()
403    {
404       return nestedColumnInfoList;
405    }
406 
407    /***
408     * @param nestedColumnInfoList The nestedColumnInfoList to set.
409     */
410    public void setNestedColumnInfoList(List nestedColumnInfoList)
411    {
412       this.nestedColumnInfoList = nestedColumnInfoList;
413    }
414 
415    private void reset()
416    {
417       this.adapterProperty = null;
418       this.defaultSort = null;
419       this.defaultValue = null;
420       this.emphasisPattern = null;
421       this.format = null;
422       this.groupKey = null;
423       this.locale = null;
424       this.property = null;
425       this.sum = null;
426       this.nestedColumnInfoList = null;
427    }
428 
429    /***
430     * Called on a Tag handler to release state.
431     * The page compiler guarantees that JSP page implementation
432     * objects will invoke this method on all tag handlers,
433     * but there may be multiple invocations on doStartTag and doEndTag in between.
434     * 
435     * @see javax.servlet.jsp.tagext.Tag#release()
436     */
437    public void release()
438    {
439       super.release();
440       reset();
441    }
442 }