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
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)
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
151
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
188
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 }