KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > tags > databinding > datagrid > DataGrid


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * $Header:$
17  */

18 package org.apache.beehive.netui.tags.databinding.datagrid;
19
20 import java.util.Iterator JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.StringWriter JavaDoc;
23 import javax.servlet.jsp.JspException JavaDoc;
24 import javax.servlet.jsp.JspContext JavaDoc;
25 import javax.servlet.jsp.tagext.SimpleTagSupport JavaDoc;
26 import javax.servlet.jsp.tagext.JspFragment JavaDoc;
27 import javax.servlet.http.HttpServletRequest JavaDoc;
28
29 import org.apache.beehive.netui.databinding.datagrid.api.rendering.DataGridTagModel;
30 import org.apache.beehive.netui.databinding.datagrid.api.rendering.StyleModel;
31 import org.apache.beehive.netui.databinding.datagrid.api.pager.PagerModel;
32 import org.apache.beehive.netui.databinding.datagrid.api.DataGridConfigFactory;
33 import org.apache.beehive.netui.databinding.datagrid.api.DataGridConfig;
34 import org.apache.beehive.netui.databinding.datagrid.api.DataGridResourceProvider;
35 import org.apache.beehive.netui.databinding.datagrid.runtime.util.PagedDataSet;
36 import org.apache.beehive.netui.databinding.datagrid.runtime.util.JspUtil;
37 import org.apache.beehive.netui.databinding.datagrid.runtime.rendering.table.TableRenderer;
38 import org.apache.beehive.netui.script.common.IDataAccessProvider;
39 import org.apache.beehive.netui.script.common.DataAccessProviderStack;
40 import org.apache.beehive.netui.tags.ExpressionHandling;
41 import org.apache.beehive.netui.tags.IBehaviorConsumer;
42 import org.apache.beehive.netui.tags.IHtmlI18n;
43 import org.apache.beehive.netui.tags.IHtmlEvents;
44 import org.apache.beehive.netui.tags.IHtmlCore;
45 import org.apache.beehive.netui.tags.html.HtmlConstants;
46 import org.apache.beehive.netui.tags.rendering.AbstractRenderAppender;
47 import org.apache.beehive.netui.tags.rendering.StringBuilderRenderAppender;
48 import org.apache.beehive.netui.tags.rendering.TableTag;
49 import org.apache.beehive.netui.tags.rendering.AbstractHtmlState;
50 import org.apache.beehive.netui.util.internal.InternalStringBuilder;
51 import org.apache.beehive.netui.util.iterator.IteratorFactory;
52 import org.apache.beehive.netui.util.Bundle;
53
54 /**
55  * <p>
56  * This tag is the containing tag for all tags and markup used to render a data grid. In its simplest form, a data
57  * grid is an HTML table containing an HTML table row for every item in a data set. The data grid also provides
58  * functionality for rendering the following major regions:
59  * <ul>
60  * <li>a header -- a header contains the top-most rows in a data grid's HTML table and is rendered using
61  * the {@link Header} tag</li>
62  * <li>data rows -- markup rendered in the data grid for each record in the data set must be contained
63  * in a {@link Rows} tag</li>
64  * <li>a footer -- a footer contains the bottom-most rows in a data grid's HTML table and is rendered using the
65  * {@link Footer} tag</li>
66  * <li>caption -- an HTML table caption appears at the top of the table and is rendered using the
67  * {@link Caption} tag.</li>
68  * </ul>
69  * In addition, a data grid can also configure and render a pager using the {@link ConfigurePager} and
70  * {@link RenderPager} tags respectively.
71  * </p>
72  * <p>
73  * Inside of the {@link Header} and {@link Rows} rendering regions, the data grid renders HTML table cells. The
74  * data grid tag set provides a set of tags that can be used render these cells with varying content including:
75  * <ul>
76  * <li>HTML &lt;th&gt; cells -- these are generally used inside the {@link Header}</li>
77  * <li>anchors -- these can be rendered using the {@link AnchorCell} tag</li>
78  * <li>images -- these can be rendered using the {@link ImageCell} tag</li>
79  * <li>image anchors-- these can be rendered using the {@link ImageAnchorCell} tag</li>
80  * <li>HTML spans -- these can be rendered using the {@link SpanCell} tag</li>
81  * </ul>
82  * The {@link TemplateCell} tag can be used as a container for arbitrary content that may be included in a cell's
83  * contents. The {@link Footer} tag's content can also use these tags.
84  * </p>
85  * <p>
86  * When the data grid renders its data set, the <code>container</code> JSP EL implicit object is exposed in the
87  * JSP's {@link JspContext} and can be referenced using the <code>${contaimer}</code> JSP EL expression. The
88  * <i>current</i> item of data from the data set can be referenced using the <code>${container.item}</code>
89  * expression. If the item had a <code>name</code> property, it could be referenced as
90  * <code>${container.item.name}</code>. By default, the data grid renders a paged data set which will only
91  * display a portion of the complete data set. The default page size is {@link PagerModel#DEFAULT_PAGE_SIZE}
92  * and can be changed by setting the {@link ConfigurePager#setPageSize(int)} attribute.
93  * </p>
94  * <p>
95  * In addition to rendering a data grid, this tag set cooperates with a set of state management services exposed
96  * via the {@link org.apache.beehive.netui.databinding.datagrid.api.DataGridStateFactory}. These services
97  * help to manage state related to paging, sorting, and filtering. For example, the first row displayed
98  * in the grid's current page and the sorts for a particular column of data are can be read / written using these
99  * state objects. The data grid will use various state information from these classes at reunder time. For example,
100  * when rendering a paged data set, the data grid will use the
101  * {@link org.apache.beehive.netui.databinding.datagrid.api.DataGridStateFactory} to obtain a {@link PagerModel}
102  * which can be used to determine the current
103  * {@link org.apache.beehive.netui.databinding.datagrid.api.pager.PagerModel#getRow()}. The grid will then
104  * use this row value to advance the grid to the appropriate page to display.
105  * </p>
106  * <p>
107  * By default, the data grid uses a configuration JavaBean which provides instances of state containers and services
108  * that are used to maintain state and render grid markup. This config object is a subclass of
109  * {@link DataGridConfig} and is obtained via the {@link DataGridConfigFactory}. The default implementation is
110  * {@link org.apache.beehive.netui.databinding.datagrid.runtime.config.DefaultDataGridConfig}. Page authors
111  * may provide their own implementations of this object and set an instance via
112  * {@link #setDataGridConfig(org.apache.beehive.netui.databinding.datagrid.api.DataGridConfig)}. This cax be
113  * used to change default behaviors, change the appearance of the pager, and change the messages displayed
114  * during rendering among other things.
115  * </p>
116  * <p>
117  * A simple, sortable, and pageable data grid that uses a first / previous // next / last pager might be
118  * written as:
119  * <pre>
120  * &lt;netui-data:dataGrid dataSource="pageScope.zooAnimals">
121  * &lt;netui-data:configurePager disableDefaultPager="true" pageAction="page" pagerFormat="firstPreviousNextLast"/>
122  * &lt;netui-data:caption>
123  * &lt;netui-data:renderPager/>
124  * &lt;netui-data:caption>
125  * &lt;netui-data:header>
126  * &lt;netui-data:heaederCell value="Animal" sortExpression="animal"/>
127  * &lt;netui-data:heaederCell value="Quantity" sortExpression="quantity"/>
128  * &lt;netui-data:heaederCell value="Details"/>
129  * &lt;/netui-data:header>
130  * &lt;netui-data:rows>
131  * &lt;netui-data:spanCell value="${container.item.animalName}"/>
132  * &lt;netui-data:spanCell value="${container.item.quantity}"/>
133  * &lt;netui-data:anchorCell action="details" value="Details">
134  * &lt;netui:parameter name="animalId" value="${container.item.animalId}"/>
135  * &lt;/netui-data:anchorCell>
136  * &lt;/netui-data:rows>
137  * &lt;/netui-data:dataGrid>
138  * </pre>
139  * This data grid would render an HTML table with a &lt;caption&gt; that contains a first / previous // next / last
140  * formated pager. The data grid would display a page with ten data rows and three columns. The header
141  * contains the column titles with clickable sorting links for sorting by the animal name and quantity. The
142  * body of the data grid contains three cells per row containing two HTML &lt;span&gt; tags and an HTML anchor
143  * which will navigate to a Page Flow action caclled <code>details</code> when clicked.
144  * </p>
145  *
146  * @jsptagref.tagdescription
147  * <p>
148  * This tag is the containing tag for all tags and markup used to render a data grid. In its simplest form, a data
149  * grid is an HTML table containing an HTML table row for every item in a data set. The data grid also provides
150  * functionality for rendering the following major regions:
151  * <ul>
152  * <li>a header -- a header contains the top-most rows in a data grid's HTML table and is rendered using
153  * the {@link Header} tag</li>
154  * <li>data rows -- markup rendered in the data grid for each record in the data set must be contained
155  * in a {@link Rows} tag</li>
156  * <li>a footer -- a footer contains the bottom-most rows in a data grid's HTML table and is rendered using the
157  * {@link Footer} tag</li>
158  * <li>caption -- an HTML table caption appears at the top of the table and is rendered using the
159  * {@link Caption} tag.</li>
160  * </ul>
161  * In addition, a data grid can also configure and render a pager using the {@link ConfigurePager} and
162  * {@link RenderPager} tags respectively.
163  * </p>
164  * <p>
165  * Inside of the {@link Header} and {@link Rows} rendering regions, the data grid renders HTML table cells. The
166  * data grid tag set provides a set of tags that can be used render these cells with varying content including:
167  * <ul>
168  * <li>HTML &lt;th&gt; cells -- these are generally used inside the {@link Header}</li>
169  * <li>anchors -- these can be rendered using the {@link AnchorCell} tag</li>
170  * <li>images -- these can be rendered using the {@link ImageCell} tag</li>
171  * <li>image anchors-- these can be rendered using the {@link ImageAnchorCell} tag</li>
172  * <li>HTML spans -- these can be rendered using the {@link SpanCell} tag</li>
173  * </ul>
174  * The {@link TemplateCell} tag can be used as a container for arbitrary content that may be included in a cell's
175  * contents. The {@link Footer} tag's content can also use these tags.
176  * </p>
177  * <p>
178  * When the data grid renders its data set, the <code>container</code> JSP EL implicit object is exposed in the
179  * JSP's {@link JspContext} and can be referenced using the <code>${contaimer}</code> JSP EL expression. The
180  * <i>current</i> item of data from the data set can be referenced using the <code>${container.item}</code>
181  * expression. If the item had a <code>name</code> property, it could be referenced as
182  * <code>${container.item.name}</code>. By default, the data grid renders a paged data set which will only
183  * display a portion of the complete data set. The default page size is {@link PagerModel#DEFAULT_PAGE_SIZE}
184  * and can be changed by setting the {@link ConfigurePager#setPageSize(int)} attribute.
185  * </p>
186  * <p>
187  * In addition to rendering a data grid, this tag set cooperates with a set of state management services exposed
188  * via the {@link org.apache.beehive.netui.databinding.datagrid.api.DataGridStateFactory}. These services
189  * help to manage state related to paging, sorting, and filtering. For example, the first row displayed
190  * in the grid's current page and the sorts for a particular column of data are can be read / written using these
191  * state objects. The data grid will use various state information from these classes at reunder time. For example,
192  * when rendering a paged data set, the data grid will use the
193  * {@link org.apache.beehive.netui.databinding.datagrid.api.DataGridStateFactory} to obtain a {@link PagerModel}
194  * which can be used to determine the current
195  * {@link org.apache.beehive.netui.databinding.datagrid.api.pager.PagerModel#getRow()}. The grid will then
196  * use this row value to advance the grid to the appropriate page to display.
197  * </p>
198  * <p>
199  * By default, the data grid uses a configuration JavaBean which provides instances of state containers and services
200  * that are used to maintain state and render grid markup. This config object is a subclass of
201  * {@link DataGridConfig} and is obtained via the {@link DataGridConfigFactory}. The default implementation is
202  * {@link org.apache.beehive.netui.databinding.datagrid.runtime.config.DefaultDataGridConfig}. Page authors
203  * may provide their own implementations of this object and set an instance via
204  * {@link #setDataGridConfig(org.apache.beehive.netui.databinding.datagrid.api.DataGridConfig)}. This cax be
205  * used to change default behaviors, change the appearance of the pager, and change the messages displayed
206  * during rendering among other things.
207  * </p>
208  * <p>
209  * A simple, sortable, and pageable data grid that uses a first / previous // next / last pager might be
210  * written as:
211  * <pre>
212  * &lt;netui-data:dataGrid dataSource="pageScope.zooAnimals">
213  * &lt;netui-data:configurePager disableDefaultPager="true" pageAction="page" pagerFormat="firstPreviousNextLast"/>
214  * &lt;netui-data:caption>
215  * &lt;netui-data:renderPager/>
216  * &lt;netui-data:caption>
217  * &lt;netui-data:header>
218  * &lt;netui-data:heaederCell value="Animal" sortExpression="animal"/>
219  * &lt;netui-data:heaederCell value="Quantity" sortExpression="quantity"/>
220  * &lt;netui-data:heaederCell value="Details"/>
221  * &lt;/netui-data:header>
222  * &lt;netui-data:rows>
223  * &lt;netui-data:spanCell value="${container.item.animalName}"/>
224  * &lt;netui-data:spanCell value="${container.item.quantity}"/>
225  * &lt;netui-data:anchorCell action="details" value="Details">
226  * &lt;netui:parameter name="animalId" value="${container.item.animalId}"/>
227  * &lt;/netui-data:anchorCell>
228  * &lt;/netui-data:rows>
229  * &lt;/netui-data:dataGrid>
230  * </pre>
231  * This data grid would render an HTML table with a &lt;caption&gt; that contains a first / previous // next / last
232  * formated pager. The data grid would display a page with ten data rows and three columns. The header
233  * contains the column titles with clickable sorting links for sorting by the animal name and quantity. The
234  * body of the data grid contains three cells per row containing two HTML &lt;span&gt; tags and an HTML anchor
235  * which will navigate to a Page Flow action caclled <code>details</code> when clicked.
236  * </p>
237  * @netui:tag name="dataGrid" body-content="scriptless"
238  * description="Containing tag for tags in the data grid tag set.
239  * Renders a pageable, sortable, and filterable HTML table containing a data set"
240  */

241 public class DataGrid
242     extends AbstractDataGridHtmlTag
243     implements IDataAccessProvider, IBehaviorConsumer, IHtmlCore, IHtmlEvents, IHtmlI18n {
244
245     private static final String JavaDoc FACET_RESOURCE = "resource";
246
247     private boolean _renderRowGroups = false;
248     private String JavaDoc _name = null;
249     private String JavaDoc _styleClassPrefix = null;
250     private String JavaDoc _stylePolicyName = null;
251     private String JavaDoc _dataSource = null;
252     private String JavaDoc _resourceBundlePath = null;
253     private DataGridConfig _dataGridConfig = null;
254     private DataGridTagModel _dataGridTagModel = null;
255     private TableTag.State _tableState = new TableTag.State();
256
257     /**
258      * The name of this tag; this value is used for error reporting.
259      * @return the String name of this tag
260      */

261     public String JavaDoc getTagName() {
262         return "DataGrid";
263     }
264
265     /**
266      * <p>
267      * Set the {@link DataGridConfig} instance that this tag will use to create state containers and other
268      * data grid objects used during rendering. Custom implementations of this class can be provided
269      * that will override the defaults set in the
270      * {@link org.apache.beehive.netui.databinding.datagrid.runtime.config.DefaultDataGridConfig}.
271      * </p>
272      * @jsptagref.attributedescription
273      * <p>
274      * Set the {@link DataGridConfig} instance that this tag will use to create state containers and other
275      * data grid objects used during rendering. Custom implementations of this class can be provided
276      * that will override the defaults set in the
277      * {@link org.apache.beehive.netui.databinding.datagrid.runtime.config.DefaultDataGridConfig}.
278      * </p>
279      * @jsptagref.attributesyntaxvalue <i>string_dataGridConfig</i>
280      * @netui:attribute required="false" rtexprvalue="true"
281      * description="The DataGridConfig instance used by the data grid to create state containers and objects for rendering"
282      */

283     public void setDataGridConfig(DataGridConfig dataGridConfig) {
284         _dataGridConfig = dataGridConfig;
285     }
286
287     /**
288      * Set the name of this data grid. The name should be a simple String that is used to uniquely identify a data
289      * grid inside of a JSP. This value is also used to namespace state information in the URL that is scoped
290      * to a data grid. Within a given scope in a page, the page author is responsible for ensuring that this
291      * name is unique.
292      * @jsptagref.attributedescription
293      * Set the name of this data grid. The name should be a simple String that is used to uniquely identify a data
294      * grid inside of a JSP. This value is also used to namespace state information in the URL that is scoped
295      * to a data grid. Within a given scope in a page, the page author is responsible for ensuring that this
296      * name is unique.
297      * @jsptagref.attributesyntaxvalue <i>string_name</i>
298      * @netui:attribute required="true"
299      * description="The name for a data grid"
300      */

301     public void setName(String JavaDoc name) {
302         _name = name;
303     }
304
305     /**
306      * <p>
307      * Set the data source that references a data set to be rendered by the data grid. The data source should be
308      * a NetUI EL expression and generally looks like a JSP EL expression without the '${' and '}' characters.
309      * For example, to reference an array of Employee objects exposed via a NetUI page input, the expression
310      * might look like:
311      * <pre>
312      * &lt;netui-data:dataGrid dataSource="pageInput.employeeArray" name="employeeGrid"&gt;
313      * </pre>
314      * This expression will be evaluated the data grid in order to obtain a reference to the data set.
315      * </p>
316      *
317      * @jsptagref.attributedescription
318      * <p>
319      * Set the data source that references a data set to be rendered by the data grid. The data source should be
320      * a NetUI EL expression and generally looks like a JSP EL expression without the '${' and '}' characters.
321      * For example, to reference an array of Employee objects exposed via a NetUI page input, the expression
322      * might look like:
323      * <pre>
324      * &lt;netui-data:dataGrid dataSource="pageInput.employeeArray" name="employeeGrid"&gt;
325      * </pre>
326      * This expression will be evaluated the data grid in order to obtain a reference to the data set.
327      * </p>
328      * @jsptagref.attributesyntaxvalue <i>string_dataSource</i>
329      * @netui:attribute required="true"
330      * description="The <code>dataSource</code> attribute determines both
331      * the source of populating data for the tag and the object to which the tag submits data."
332      */

333     public void setDataSource(String JavaDoc dataSource) {
334         _dataSource = dataSource;
335     }
336
337     /**
338      * <p>
339      * Set the style class prefix used to namespace style class names rendered as attributes on HTML tags
340      * generated by the data grid. For example, when using the default style policy without setting this
341      * attribute, the style rendered for the generated HTML table tag will be:
342      * <pre>
343      * &lt;table class="datagrid"&gt;
344      * </pre>
345      * With the style class prefix of <code>foo</code>, the rendered HTML style class will be:
346      * <pre>
347      * &lt;table class="foo"&gt;
348      * </pre>
349      * </p>
350      * @jsptagref.attributedescription
351      * <p>
352      * Set the style class prefix used to namespace style class names rendered as attributes on HTML tags
353      * generated by the data grid. For example, when using the default style policy without setting this
354      * attribute, the style rendered for the generated HTML table tag will be:
355      * <pre>
356      * &lt;table class="datagrid"&gt;
357      * </pre>
358      * With the style class prefix of <code>foo</code>, the rendered HTML style class will be:
359      * <pre>
360      * &lt;table class="foo"&gt;
361      * </pre>
362      * </p>
363      * @jsptagref.attributesyntaxvalue <i>string_styleClassPrefix</i>
364      * @netui:attribute required="false" rtexprvalue="true"
365      * description="The style class prefix used when setting CSS style classes on HTML elements generated by the data grid."
366      */

367     public void setStyleClassPrefix(String JavaDoc styleClassPrefix) {
368         _styleClassPrefix = styleClassPrefix;
369     }
370
371     /**
372      * <p>
373      * Set the resource bundle path used when getting messages from a {@link DataGridResourceProvider} during
374      * data grid rendering. The resource bundle provided here will entirely override messages obtained from
375      * the {@link DataGridResourceProvider} and must include all message keys that are used for rendering.
376      * In order to replace individual messages, use the behavior available from the
377      * {@link #setBehavior(String, Object, String)} method.
378      * </p>
379      * @jsptagref.attributedescription
380      * <p>
381      * Set the resource bundle path used when getting messages from a {@link DataGridResourceProvider} during
382      * data grid rendering. The resource bundle provided here will entirely override messages obtained from
383      * the {@link DataGridResourceProvider} and must include all message keys that are used for rendering.
384      * In order to replace individual messages, use the behavior available from the
385      * {@link #setBehavior(String, Object, String)} method.
386      * </p>
387      * @jsptagref.attributesyntaxvalue <i>string_resourceBundlePath</i>
388      * @netui:attribute required="false" rtexprvalue="true"
389      * description="A resource bundle path that can be used to replace the default strings rendered by a data grid"
390      */

391     public void setResourceBundlePath(String JavaDoc resourceBundlePath) {
392         _resourceBundlePath = resourceBundlePath;
393     }
394
395     /**
396      * <p>
397      * Set the name of a CSS policy to use when rendering HTML elements in a data grid. The data grid supports the
398      * default style policy names defined here
399      * {@link org.apache.beehive.netui.databinding.datagrid.runtime.config.DefaultDataGridConfig#getStyleModel(String, String)}.
400      * </p>
401      * @jsptagref.attributedescription
402      * <p>
403      * Set the name of a CSS policy to use when rendering HTML elements in a data grid. The data grid supports the
404      * default style policy names defined here
405      * {@link org.apache.beehive.netui.databinding.datagrid.runtime.config.DefaultDataGridConfig#getStyleModel(String, String)}.
406      * </p>
407      * @jsptagref.attributesyntaxvalue <i>string_stylePolicy</i>
408      * @netui:attribute required="false" rtexprvalue="true"
409      * description="Set the name of a CSS policy used when rendering a data grid."
410      */

411     public void setStyleClassPolicy(String JavaDoc stylePolicy) {
412         _stylePolicyName = stylePolicy;
413     }
414
415     /**
416      * <p>
417      * Sets a boolean that enables / disables rendering of HTML table row groups in the data grid. When
418      * row group rendering is enabled, the data grid tags will produce the thead, tbody, and tfoot HTML tags
419      * via the {@link Header}, {@link Rows}, and {@link Footer} tags respectively. In addition, as per the
420      * <a HREF="http://www.w3.org/TR/REC-html40/struct/tables.html#h-11.2.3">HTML specification</a>, the data
421      * grid will reorder the output of the row groups to in order to produce valid HTML. When row group rendering
422      * is enabled and a page is using JavaScript, the data grid <b>must</b> be nested inside of a NetUI
423      * {@link org.apache.beehive.netui.tags.javascript.ScriptContainer} in order for JavaScript rendering
424      * to be ordered correctly. Legacy JavaScript script mode is not supported by the data grid.
425      * </p>
426      * @jsptagref.attributedescription
427      * <p>
428      * Sets a boolean that enables / disables rendering of HTML table row groups in the data grid. When
429      * row group rendering is enabled, the data grid tags will produce the thead, tbody, and tfoot HTML tags
430      * via the {@link Header}, {@link Rows}, and {@link Footer} tags respectively. In addition, as per the
431      * <a HREF="http://www.w3.org/TR/REC-html40/struct/tables.html#h-11.2.3">HTML specification</a>, the data
432      * grid will reorder the output of the row groups to in order to produce valid HTML. When row group rendering
433      * is enabled and a page is using JavaScript, the data grid <b>must</b> be nested inside of a NetUI
434      * {@link org.apache.beehive.netui.tags.javascript.ScriptContainer} in order for JavaScript rendering
435      * to be ordered correctly. Legacy JavaScript script mode is not supported by the data grid.
436      * </p>
437      * @jsptagref.attributesyntaxvalue <i>boolean_renderRowGroups</i>
438      * @netui:attribute required="false" rtexprvalue="true"
439      * description="Set a boolean flag for enabling / disabling row group rendering"
440      */

441     public void setRenderRowGroups(boolean renderRowGroups) {
442         _renderRowGroups = renderRowGroups;
443     }
444
445     /**
446      * Sets the onClick JavaScript event for the HTML table tag.
447      *
448      * @param onClick the onClick event.
449      * @jsptagref.attributedescription The onClick JavaScript event for the HTML table tag.
450      * @jsptagref.attributesyntaxvalue <i>string_onClick</i>
451      * @netui:attribute required="false" rtexprvalue="true" description="The onClick JavaScript event for the HTML table tag."
452      */

453     public void setOnClick(String JavaDoc onClick) {
454         _tableState.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, HtmlConstants.ONCLICK, onClick);
455     }
456
457     /**
458      * Sets the onDblClick JavaScript event for the HTML tag.
459      *
460      * @param onDblClick the onDblClick event.
461      * @jsptagref.attributedescription The onDblClick JavaScript event for the HTML tag.
462      * @jsptagref.attributesyntaxvalue <i>string_onDblClick</i>
463      * @netui:attribute required="false" rtexprvalue="true" description="The onDblClick JavaScript event for the HTML tag."
464      */

465     public void setOnDblClick(String JavaDoc onDblClick) {
466         _tableState.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, HtmlConstants.ONDBLCLICK, onDblClick);
467     }
468
469     /**
470      * Sets the onKeyDown JavaScript event for the HTML tag.
471      *
472      * @param onKeyDown the onKeyDown event.
473      * @jsptagref.attributedescription The onKeyDown JavaScript event for the HTML tag.
474      * @jsptagref.attributesyntaxvalue <i>string_onKeyDown</i>
475      * @netui:attribute required="false" rtexprvalue="true" description="The onKeyDown JavaScript event for the HTML tag."
476      */

477     public void setOnKeyDown(String JavaDoc onKeyDown) {
478         _tableState.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, HtmlConstants.ONKEYDOWN, onKeyDown);
479     }
480
481     /**
482      * Sets the onKeyUp JavaScript event for the HTML tag.
483      *
484      * @param onKeyUp the onKeyUp event.
485      * @jsptagref.attributedescription The onKeyUp JavaScript event for the HTML tag.
486      * @jsptagref.attributesyntaxvalue <i>string_onKeyUp</i>
487      * @netui:attribute required="false" rtexprvalue="true" description="The onKeyUp JavaScript event for the HTML tag."
488      */

489     public void setOnKeyUp(String JavaDoc onKeyUp) {
490         _tableState.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, HtmlConstants.ONKEYUP, onKeyUp);
491     }
492
493     /**
494      * Sets the onKeyPress JavaScript event for the HTML tag.
495      *
496      * @param onKeyPress the onKeyPress event.
497      * @jsptagref.attributedescription The onKeyPress JavaScript event for the HTML tag.
498      * @jsptagref.attributesyntaxvalue <i>string_onKeyPress</i>
499      * @netui:attribute required="false" rtexprvalue="true" description="The onKeyPress JavaScript event for the HTML tag."
500      */

501     public void setOnKeyPress(String JavaDoc onKeyPress) {
502         _tableState.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, HtmlConstants.ONKEYPRESS, onKeyPress);
503     }
504
505     /**
506      * Sets the onMouseDown JavaScript event for the HTML tag.
507      *
508      * @param onMouseDown the onMouseDown event.
509      * @jsptagref.attributedescription The onMouseDown JavaScript event for the HTML tag.
510      * @jsptagref.attributesyntaxvalue <i>string_onMouseDown</i>
511      * @netui:attribute required="false" rtexprvalue="true" description="The onMouseDown JavaScript event for the HTML tag."
512      */

513     public void setOnMouseDown(String JavaDoc onMouseDown) {
514         _tableState.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, HtmlConstants.ONMOUSEDOWN, onMouseDown);
515     }
516
517     /**
518      * Sets the onMouseUp JavaScript event for the HTML tag.
519      *
520      * @param onMouseUp the onMouseUp event.
521      * @jsptagref.attributedescription The onMouseUp JavaScript event for the HTML tag.
522      * @jsptagref.attributesyntaxvalue <i>string_onMouseUp</i>
523      * @netui:attribute required="false" rtexprvalue="true" description="The onMouseUp JavaScript event for the HTML tag."
524      */

525     public void setOnMouseUp(String JavaDoc onMouseUp) {
526         _tableState.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, HtmlConstants.ONMOUSEUP, onMouseUp);
527     }
528
529     /**
530      * Sets the onMouseMove JavaScript event for the HTML tag.
531      *
532      * @param onMouseMove the onMouseMove event.
533      * @jsptagref.attributedescription The onMouseMove JavaScript event for the HTML tag.
534      * @jsptagref.attributesyntaxvalue <i>string_onMouseMove</i>
535      * @netui:attribute required="false" rtexprvalue="true" description="The onMouseMove JavaScript event for the HTML tag."
536      */

537     public void setOnMouseMove(String JavaDoc onMouseMove) {
538         _tableState.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, HtmlConstants.ONMOUSEMOVE, onMouseMove);
539     }
540
541     /**
542      * Sets the onMouseOut JavaScript event for the HTML tag.
543      *
544      * @param onMouseOut the onMouseOut event.
545      * @jsptagref.attributedescription The onMouseOut JavaScript event for the HTML tag.
546      * @jsptagref.attributesyntaxvalue <i>string_onMouseOut</i>
547      * @netui:attribute required="false" rtexprvalue="true" description="The onMouseOut JavaScript event for the HTML tag."
548      */

549     public void setOnMouseOut(String JavaDoc onMouseOut) {
550         _tableState.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, HtmlConstants.ONMOUSEOUT, onMouseOut);
551     }
552
553     /**
554      * Sets the onMouseOver JavaScript event for the HTML tag.
555      *
556      * @param onMouseOver the onMouseOver event.
557      * @jsptagref.attributedescription The onMouseOver JavaScript event for the HTML table tag..
558      * @jsptagref.attributesyntaxvalue <i>string_onMouseOver</i>
559      * @netui:attribute required="false" rtexprvalue="true" description="The onMouseOver JavaScript event for the HTML tag."
560      */

561     public void setOnMouseOver(String JavaDoc onMouseOver) {
562         _tableState.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT, HtmlConstants.ONMOUSEOVER, onMouseOver);
563     }
564
565     /**
566      * Sets the style for the HTML table tag.
567      *
568      * @param style the html style.
569      * @jsptagref.attributedescription The style for the HTML table tag.
570      * @jsptagref.attributesyntaxvalue <i>string_style</i>
571      * @netui:attribute required="false" rtexprvalue="true" description="The style for the HTML table tag"
572      */

573     public void setStyle(String JavaDoc style) {
574         if("".equals(style)) return;
575
576         _tableState.style = style;
577     }
578
579     /**
580      * Sets the style class for the HTML table tag.
581      *
582      * @param styleClass the html style class.
583      * @jsptagref.attributedescription The style class for the HTML table tag.
584      * @jsptagref.attributesyntaxvalue <i>string_style_class</i>
585      * @netui:attribute required="false" rtexprvalue="true" description="The style class for the HTML table tag."
586      */

587     public void setStyleClass(String JavaDoc styleClass) {
588         if("".equals(styleClass)) return;
589
590         _tableState.styleClass = styleClass;
591     }
592
593     /**
594      * Sets the value of the title attribute for the HTML table tag.
595      *
596      * @param title the title
597      * @jsptagref.attributedescription The title for the HTML table tag.
598      * @jsptagref.attributesyntaxvalue <i>string_title</i>
599      * @netui:attribute required="false" rtexprvalue="true" description="The title for the HTML table tag."
600      */

601     public void setTitle(String JavaDoc title) {
602         _tableState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, HtmlConstants.TITLE, title);
603     }
604
605     /**
606      * Sets the lang attribute for the HTML table tag.
607      * @param lang the lang
608      * @jsptagref.attributedescription The lang for the HTML table tag.
609      * @jsptagref.attributesyntaxvalue <i>string_lang</i>
610      * @netui:attribute required="false" rtexprvalue="true" description="The lang for the HTML table tag."
611      */

612     public void setLang(String JavaDoc lang)
613     {
614         _tableState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, HtmlConstants.LANG, lang);
615     }
616
617     /**
618      * Sets the dir attribute for the HTML table tag.
619      * @param dir the dir
620      * @jsptagref.attributedescription The dir for the HTML table tag.
621      * @jsptagref.attributesyntaxvalue <i>string_dir</i>
622      * @netui:attribute required="false" rtexprvalue="true"
623      * description="The dir for the HTML table tag."
624      */

625     public void setDir(String JavaDoc dir)
626     {
627         _tableState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, HtmlConstants.DIR, dir);
628     }
629
630     /**
631      * Sets the summary attribute for the HTML table tag.
632      * @param summary the summary
633      * @jsptagref.attributedescription The summary for the HTML table tag.
634      * @jsptagref.attributesyntaxvalue <i>string_summary</i>
635      * @netui:attribute required="false" rtexprvalue="true"
636      * description="The summary for the HTML table tag."
637      */

638     public void setSummary(String JavaDoc summary)
639     {
640         _tableState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, HtmlConstants.SUMMARY, summary);
641     }
642
643     /**
644      * Sets the width attribute for the HTML table tag.
645      * @param width the width
646      * @jsptagref.attributedescription The width for the HTML table tag.
647      * @jsptagref.attributesyntaxvalue <i>string_width</i>
648      * @netui:attribute required="false" rtexprvalue="true" description="The width attribute for the HTML table tag."
649      */

650     public void setWidth(String JavaDoc width)
651     {
652         _tableState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, HtmlConstants.WIDTH, width);
653     }
654
655     /**
656      * Sets the border attribute for the HTML table tag.
657      * @param border
658      * @jsptagref.attributedescription The border attribute for the HTML table tag.
659      * @jsptagref.attributesyntaxvalue <i>string_dir</i>
660      * @netui:attribute required="false" rtexprvalue="true" description="The border attribute for the HTML table tag."
661      */

662     public void setBorder(String JavaDoc border)
663     {
664         _tableState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, HtmlConstants.BORDER, border);
665     }
666
667     /**
668      * Sets the frame attribute for the HTML table tag.
669      * @param frame the frame
670      * @jsptagref.attributedescription The frame attribute for the HTML table tag.
671      * @jsptagref.attributesyntaxvalue <i>string_frame</i>
672      * @netui:attribute required="false" rtexprvalue="true"
673      * description="The frame for the HTML table tag."
674      */

675     public void setFrame(String JavaDoc frame)
676     {
677         _tableState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, HtmlConstants.FRAME, frame);
678     }
679
680     /**
681      * Sets the rules attribute for the HTML table tag.
682      * @param rules the rules
683      * @jsptagref.attributedescription The rules attribute for the HTML table tag.
684      * @jsptagref.attributesyntaxvalue <i>string_rules</i>
685      * @netui:attribute required="false" rtexprvalue="true" description="The rules attribute for the HTML table tag."
686      */

687     public void setRules(String JavaDoc rules)
688     {
689         _tableState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, HtmlConstants.RULES, rules);
690     }
691
692     /**
693      * Sets the cellspacing attribute for the HTML table tag.
694      * @param cellspacing the cell spacing
695      * @jsptagref.attributedescription The cellspacing for the HTML table tag.
696      * @jsptagref.attributesyntaxvalue <i>string_cellspacing</i>
697      * @netui:attribute required="false" rtexprvalue="true" description="The cellspacing for the HTML table tag."
698      */

699     public void setCellspacing(String JavaDoc cellspacing)
700     {
701         _tableState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, HtmlConstants.CELLSPACING, cellspacing);
702     }
703
704     /**
705      * Sets the cellpadding attribute for the HTML table tag.
706      * @param cellpadding the cell padding
707      * @jsptagref.attributedescription The cellpadding for the HTML table tag.
708      * @jsptagref.attributesyntaxvalue <i>string_cellpadding</i>
709      * @netui:attribute required="false" rtexprvalue="true" description="The cellpadding for the HTML table tag."
710      */

711     public void setCellpadding(String JavaDoc cellpadding)
712     {
713         _tableState.registerAttribute(AbstractHtmlState.ATTR_GENERAL, HtmlConstants.CELLPADDING, cellpadding);
714     }
715
716     /**
717      * Set the name of the tagId for the HTML table tag.
718      *
719      * @param tagId the the name of the tagId for the table tag.
720      * @jsptagref.attributedescription The tagId for the HTML table tag.
721      * @jsptagref.attributesyntaxvalue <i>string_tagId</i>
722      * @netui:attribute required="false" rtexprvalue="true"
723      * description="String value. Sets the id (or name) attribute of the rendered HTML tag. "
724      */

725     public void setTagId(String JavaDoc tagId)
726         throws JspException JavaDoc {
727         applyTagId(_tableState, tagId);
728     }
729
730     /**
731      * <p>
732      * Implementation of the {@link IBehaviorConsumer} interface that extends the functionality of this
733      * tag beyond that exposed via the JSP tag attributes. This method accepts the following facets:
734      * <table>
735      * <tr><td>Facet Name</td><td>Operation</td></tr>
736      * <tr><td><code>resource</code></td><td>Adds or overrides a data grid resource key with a new value.</td></tr>
737      * </table>
738      * A new resource key is added in order to override a value defined in
739      * {@link org.apache.beehive.netui.databinding.datagrid.api.rendering.IDataGridMessageKeys}. When a message
740      * is overridden or added here, the page author is able to override a single string resource such as a
741      * pager mesage or sort href.
742      * </p>
743      * @param name the name of the behavior
744      * @param value the value of the behavior
745      * @param facet th ebehavior's facet
746      * @throws JspException when the behavior's facet isnot recognized
747     */

748     public void setBehavior(String JavaDoc name, Object JavaDoc value, String JavaDoc facet)
749             throws JspException JavaDoc {
750         if(facet != null && facet.equals(FACET_RESOURCE)) {
751             _dataGridTagModel.addResourceOverride(name, (value != null ? value.toString() : null));
752         }
753         else {
754             String JavaDoc s = Bundle.getString("Tags_BehaviorFacetNotSupported", new Object JavaDoc[]{facet});
755             throw new JspException JavaDoc(s);
756         }
757     }
758
759     /**
760      * <p>
761      * Render a data grid. This method implements the logic used to iterate through the data grid's rendering states
762      * defined in {@link DataGridTagModel}.
763      * </p>
764      * @throws JspException when an error occurs evaluating the tag's body
765      * @throws IOException when an error occurs writing to the output strema
766      */

767     public void doTag()
768             throws JspException JavaDoc, IOException JavaDoc {
769
770         // ensure the dataSource is a valid expression
771
String JavaDoc dataSource = getDataSource();
772         ExpressionHandling expr = new ExpressionHandling(this);
773         String JavaDoc validExpr = expr.ensureValidExpression(dataSource, "dataSource", "DataSourceError");
774         Object JavaDoc ds = expr.evaluateExpression(validExpr, "dataSource", getPageContext());
775         Iterator JavaDoc iterator = IteratorFactory.createIterator(ds);
776
777         JspContext JavaDoc jspContext = getJspContext();
778         HttpServletRequest JavaDoc request = JspUtil.getRequest(jspContext);
779
780         if(_dataGridConfig == null)
781             _dataGridConfig = DataGridConfigFactory.getInstance();
782
783         TableRenderer tableRenderer = new TableRenderer(request);
784         PagedDataSet dataSet = new PagedDataSet(dataSource, iterator);
785
786         StyleModel styleModel = _dataGridConfig.getStyleModel(_stylePolicyName, _styleClassPrefix);
787
788         DataGridResourceProvider resourceProvider = null;
789         if(_resourceBundlePath == null)
790             resourceProvider = _dataGridConfig.getDefaultResourceProvider();
791         else
792             resourceProvider = _dataGridConfig.getResourceProvider(_resourceBundlePath);
793         resourceProvider.setLocale(JspUtil.getLocale(jspContext));
794
795         _dataGridTagModel = new DataGridTagModel(_name, _dataGridConfig, jspContext);
796         _dataGridTagModel.setDataSet(dataSet);
797         _dataGridTagModel.setStyleModel(styleModel);
798         _dataGridTagModel.setTableRenderer(tableRenderer);
799         _dataGridTagModel.setResourceProvider(resourceProvider);
800         _dataGridTagModel.setRenderRowGroups(_renderRowGroups);
801
802         JspFragment JavaDoc fragment = getJspBody();
803         if(fragment != null) {
804             String JavaDoc javascript = null;
805             /* render any JavaScript needed to support framework features */
806             if (_tableState.id != null) {
807                 javascript = renderNameAndId(request, _tableState, null);
808             }
809
810             boolean addedDataAccessProvider = false;
811             try {
812                 InternalStringBuilder builder = new InternalStringBuilder(2048);
813                 AbstractRenderAppender appender = new StringBuilderRenderAppender(builder);
814
815                 /* todo: perf -- this doesn't need to happen when the data set is empty */
816                 DataAccessProviderStack.addDataAccessProvider(this, getJspContext());
817                 DataGridUtil.putDataGridTagModel(getJspContext(), _dataGridTagModel);
818                 addedDataAccessProvider = true;
819
820                 StringWriter JavaDoc sw = new StringWriter JavaDoc();
821                 /*
822                    allow sub-tags to do work during START before rendering
823                    this makes it possible to have tags out of order and to
824                    have rendering work correctly
825                  */

826                 /* todo: perf -- should you be able to turn this off for perf? */
827                 fragment.invoke(sw);
828
829                 /* todo: this needs to move into the DataGridTagModel */
830                 PagerModel pm = _dataGridTagModel.getState().getPagerModel();
831                 _dataGridTagModel.getDataSet().createWindow(pm.getRow(), pm.getPageSize());
832
833                 /* now that the model objects have been initialized, it's time to start rendering */
834                 _dataGridTagModel.changeRenderState(DataGridTagModel.RENDER_STATE_START);
835
836                 if(!_dataGridTagModel.isDisableDefaultPagerRendering())
837                     _dataGridTagModel.renderPager(appender);
838
839                 _tableState.styleClass = styleModel.getTableClass();
840                 tableRenderer.openTable(_tableState, appender);
841
842                 /* render the caption */
843                 _dataGridTagModel.changeRenderState(DataGridTagModel.RENDER_STATE_CAPTION);
844                 sw = new StringWriter JavaDoc();
845                 fragment.invoke(sw);
846                 String JavaDoc caption = sw.toString();
847                 if(caption != null)
848                     appender.append(caption);
849
850                 /* render the header */
851                 _dataGridTagModel.changeRenderState(DataGridTagModel.RENDER_STATE_HEADER);
852                 sw = new StringWriter JavaDoc();
853                 fragment.invoke(sw);
854                 String JavaDoc header = sw.toString();
855                 if(header != null)
856                     appender.append(header);
857
858                 /* intermediate storage for the body and footer content
859                    these are required by the HTML spec:
860                        http://www.w3.org/TR/REC-html40/struct/tables.html#h-11.2.3
861                    as when the row groups are used, they must be re-ordered so that
862                    <tfoot> preceeds <tbody>
863                  */

864
865                 String JavaDoc tbody = null;
866                 String JavaDoc tfoot = null;
867
868                 /* render the body */
869                 _dataGridTagModel.changeRenderState(DataGridTagModel.RENDER_STATE_GRID);
870                 sw = new StringWriter JavaDoc();
871                 fragment.invoke(sw);
872                 tbody = sw.toString();
873
874                 /* render the footer */
875                 _dataGridTagModel.changeRenderState(DataGridTagModel.RENDER_STATE_FOOTER);
876                 sw = new StringWriter JavaDoc();
877                 fragment.invoke(sw);
878                 String JavaDoc footer = sw.toString();
879                 String JavaDoc trimmed = footer.trim();
880                 if(footer != null && !trimmed.trim().equals(""))
881                     tfoot = footer;
882
883                 if(_dataGridTagModel.isRenderRowGroups()) {
884                     if(tfoot != null)
885                         appender.append(tfoot);
886                     appender.append(tbody);
887                 }
888                 else {
889                     appender.append(tbody);
890                     if(tfoot != null)
891                         appender.append(tfoot);
892                 }
893
894                 tableRenderer.closeTable(appender);
895
896                 if(javascript != null)
897                     appender.append(javascript);
898
899                 _dataGridTagModel.changeRenderState(DataGridTagModel.RENDER_STATE_END);
900
901                 write(builder.toString());
902             }
903             finally {
904                 if(addedDataAccessProvider) {
905                     DataAccessProviderStack.removeDataAccessProvider(getJspContext());
906                     DataGridUtil.removeDataGridTagModel(getJspContext());
907                 }
908             }
909         }
910     }
911
912     /* ===========================================================
913      *
914      * IDataAccessProvider implementation
915      *
916      * ===========================================================
917      */

918
919     /**
920      * Get the index of the current item in the data set. This is a zero-based absolute
921      * index into the entire data set being rendered by the data grid. This value
922      * should only be data bound inside of the {@link Rows}.
923      * @return the index of the current item
924      */

925     public int getCurrentIndex() {
926         return _dataGridTagModel.getCurrentIndex();
927     }
928
929     /**
930      * Get the current item in the data set. As the data grid iterates over the data set, this
931      * value will change to provide access to the current item in the data set. This value
932      * should only be data bound inside of the {@link Rows}.
933      * @return the current item
934      */

935     public Object JavaDoc getCurrentItem() {
936         return _dataGridTagModel.getCurrentItem();
937     }
938
939     /**
940      * Get metadata for the current item. This operation is unsupported on the data grid.
941      * @return the metadata for the current item
942      * @throws UnsupportedOperationException as this method is unsupported
943      */

944     public Object JavaDoc getCurrentMetadata() {
945         throw new UnsupportedOperationException JavaDoc(Bundle.getErrorString("Tags_DataAccessProvider_metadataUnsupported",
946                 new Object JavaDoc[]{getTagName()}));
947     }
948
949     /**
950      * Get the data source for the data grid. This value returns a NetUI EL expression which can
951      * be evaluated by the NetUI tag API.
952      * @return the expression
953      */

954     public String JavaDoc getDataSource() {
955         return "{" + _dataSource + "}";
956     }
957
958     /**
959      * Get the parent data access provider. This method requires access to the tag hierarchy and is not
960      * usable across tag file or JSP include rendering boundaries. The result of this method is used for
961      * evaluating expressions of the form <code>${container.container}</code> where this tag's parent
962      * repeating tag is referenced.
963      * @return the parent data access provider
964      */

965     public IDataAccessProvider getProviderParent() {
966         /* todo: support nested data grids. this should be done via the stack of objects in the PageContext */
967         return (IDataAccessProvider)SimpleTagSupport.findAncestorWithClass(this, IDataAccessProvider.class);
968     }
969 }
970
Popular Tags