001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: * $Header:$
018: */
019: package org.apache.beehive.netui.tags.databinding.datagrid;
020:
021: import org.apache.beehive.netui.util.internal.InternalStringBuilder;
022:
023: import java.io.IOException;
024: import java.io.StringWriter;
025: import javax.servlet.jsp.JspException;
026: import javax.servlet.jsp.JspContext;
027: import javax.servlet.jsp.tagext.JspFragment;
028: import javax.servlet.http.HttpServletRequest;
029:
030: import org.apache.beehive.netui.databinding.datagrid.api.rendering.DataGridTagModel;
031: import org.apache.beehive.netui.databinding.datagrid.api.rendering.StyleModel;
032: import org.apache.beehive.netui.databinding.datagrid.runtime.rendering.table.TableRenderer;
033: import org.apache.beehive.netui.databinding.datagrid.runtime.util.JspUtil;
034: import org.apache.beehive.netui.tags.IHtmlEvents;
035: import org.apache.beehive.netui.tags.IHtmlI18n;
036: import org.apache.beehive.netui.tags.html.HtmlConstants;
037: import org.apache.beehive.netui.tags.rendering.StringBuilderRenderAppender;
038: import org.apache.beehive.netui.tags.rendering.AbstractRenderAppender;
039: import org.apache.beehive.netui.tags.rendering.TrTag;
040: import org.apache.beehive.netui.tags.rendering.TBodyTag;
041: import org.apache.beehive.netui.tags.rendering.AbstractHtmlState;
042: import org.apache.beehive.netui.util.Bundle;
043:
044: /**
045: * <p>
046: * The Rows tag is used to render a table row(s) that contain the data from a data set displayed
047: * in a data grid. The rows rendered here render after the header reders with the {@link Header} and before
048: * the footer renders in the {@link Footer}. The body of this tag usually contains the data grid's "cell" tags
049: * which are used to render HTML table cells inside of the rows rendered by this tag. Such tags include:
050: * <ul>
051: * <li>{@link AnchorCell} which is used to render anchors</li>
052: * <li>{@link ImageAnchorCell} which is used to render clickable images</li>
053: * <li>{@link ImageCell} which is used to render an image</li>
054: * <li>{@link SpanCell} which is used to render an HTML span with data bound content</li>
055: * <li>{@link TemplateCell} which can contain arbitrary content for {@link javax.servlet.jsp.tagext.SimpleTag}</li>
056: * </ul>
057: * </p>
058: * <p>
059: * The attribute setters in this class are used to add attributes to the <tbody> tag which will be rendered
060: * when row groups are enabled. When row group rendering is disabled, attributes set here do not render.
061: * </p>
062: * <p>
063: * Because this tag renders inside of an HTML table, it by default renders an HTML
064: * <tr> tag to represent a table row. Table row tag rendering can be disabled using the {@link #setRenderRow(boolean)}
065: * attribute. When this is disabled, the page author is responsible for maintaining the integrity of the
066: * HTML table by writing <tr> tags manually or by using the {@link Row} tag. When this tag is rendering
067: * it does not produce table cells; the contents of the table row in the footer is entirely left to the
068: * page author. With row rendering disabled, it is also possible to add multiple table rows to the
069: * end of a data grid.
070: * </p>
071: * <p>
072: * The set of JSP implicit objects available to the body include:
073: * <ul>
074: * <li><code>dataGridModel</code> -- the {@link org.apache.beehive.netui.databinding.datagrid.api.rendering.DataGridTagModel}
075: * for the cell's containing data grid.</li>
076: * </ul>
077: * </p>
078: * @jsptagref.tagdescription
079: * <p>
080: * The Rows tag is used to render a table row(s) that contain the data from a data set displayed
081: * in a data grid. The rows rendered here render after the header reders with the {@link Header} and before
082: * the footer renders in the {@link Footer}. The body of this tag usually contains the data grid's "cell" tags
083: * which are used to render HTML table cells inside of the rows rendered by this tag. Such tags include:
084: * <ul>
085: * <li>{@link AnchorCell} which is used to render anchors</li>
086: * <li>{@link ImageAnchorCell} which is used to render clickable images</li>
087: * <li>{@link ImageCell} which is used to render an image</li>
088: * <li>{@link SpanCell} which is used to render an HTML span with data bound content</li>
089: * <li>{@link TemplateCell} which can contain arbitrary content for {@link javax.servlet.jsp.tagext.SimpleTag}</li>
090: * </ul>
091: * </p>
092: * <p>
093: * The attribute setters in this class are used to add attributes to the <tbody> tag which will be rendered
094: * when row groups are enabled. When row group rendering is disabled, attributes set here do not render.
095: * </p>
096: * <p>
097: * Because this tag renders inside of an HTML table, it by default renders an HTML
098: * <tr> tag to represent a table row. Table row tag rendering can be disabled using the {@link #setRenderRow(boolean)}
099: * attribute. When this is disabled, the page author is responsible for maintaining the integrity of the
100: * HTML table by writing <tr> tags manually or by using the {@link Row} tag. When this tag is rendering
101: * it does not produce table cells; the contents of the table row in the footer is entirely left to the
102: * page author. With row rendering disabled, it is also possible to add multiple table rows to the
103: * end of a data grid.
104: * </p>
105: * <p>
106: * The set of JSP implicit objects available to the body include:
107: * <ul>
108: * <li><code>dataGridModel</code> -- the {@link org.apache.beehive.netui.databinding.datagrid.api.rendering.DataGridTagModel}
109: * for the cell's containing data grid.</li>
110: * </ul>
111: * </p>
112: *
113: * @netui:tag name="rows" body-content="scriptless"
114: * description="Renders the data rows into a NetUI data grid"
115: */
116: public class Rows extends AbstractDataGridHtmlTag implements
117: IHtmlEvents, IHtmlI18n {
118:
119: private boolean _renderRow = true;
120: private TBodyTag.State _tbodyTag = new TBodyTag.State();
121:
122: /**
123: * The name of this tag; this value is used for error reporting.
124: * @return the String name of this tag
125: */
126: public String getTagName() {
127: return "Rows";
128: }
129:
130: /**
131: * Sets the onClick JavaScript event for the HTML tbody tag.
132: *
133: * @param onClick the onClick event.
134: * @jsptagref.attributedescription The onClick JavaScript event for the HTML tbody tag.
135: * @jsptagref.attributesyntaxvalue <i>string_onClick</i>
136: * @netui:attribute required="false" rtexprvalue="true" description="The onClick JavaScript event for the HTML tbody tag."
137: */
138: public void setOnClick(String onClick) {
139: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT,
140: HtmlConstants.ONCLICK, onClick);
141: }
142:
143: /**
144: * Sets the onDblClick JavaScript event for the HTML tbody tag.
145: *
146: * @param onDblClick the onDblClick event.
147: * @jsptagref.attributedescription The onDblClick JavaScript event for the HTML tbody tag.
148: * @jsptagref.attributesyntaxvalue <i>string_onDblClick</i>
149: * @netui:attribute required="false" rtexprvalue="true" description="The onDblClick JavaScript event for the HTML tbody tag."
150: */
151: public void setOnDblClick(String onDblClick) {
152: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT,
153: HtmlConstants.ONDBLCLICK, onDblClick);
154: }
155:
156: /**
157: * Sets the onKeyDown JavaScript event for the HTML tbody tag.
158: *
159: * @param onKeyDown the onKeyDown event.
160: * @jsptagref.attributedescription The onKeyDown JavaScript event for the HTML tbody tag.
161: * @jsptagref.attributesyntaxvalue <i>string_onKeyDown</i>
162: * @netui:attribute required="false" rtexprvalue="true" description="The onKeyDown JavaScript event for the HTML tbody tag."
163: */
164: public void setOnKeyDown(String onKeyDown) {
165: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT,
166: HtmlConstants.ONKEYDOWN, onKeyDown);
167: }
168:
169: /**
170: * Sets the onKeyUp JavaScript event for the HTML tbody tag.
171: *
172: * @param onKeyUp the onKeyUp event.
173: * @jsptagref.attributedescription The onKeyUp JavaScript event for the HTML tbody tag.
174: * @jsptagref.attributesyntaxvalue <i>string_onKeyUp</i>
175: * @netui:attribute required="false" rtexprvalue="true" description="The onKeyUp JavaScript event for the HTML tbody tag."
176: */
177: public void setOnKeyUp(String onKeyUp) {
178: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT,
179: HtmlConstants.ONKEYUP, onKeyUp);
180: }
181:
182: /**
183: * Sets the onKeyPress JavaScript event for the HTML tbody tag.
184: *
185: * @param onKeyPress the onKeyPress event.
186: * @jsptagref.attributedescription The onKeyPress JavaScript event for the HTML tbody tag.
187: * @jsptagref.attributesyntaxvalue <i>string_onKeyPress</i>
188: * @netui:attribute required="false" rtexprvalue="true" description="The onKeyPress JavaScript event for the HTML tbody tag."
189: */
190: public void setOnKeyPress(String onKeyPress) {
191: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT,
192: HtmlConstants.ONKEYPRESS, onKeyPress);
193: }
194:
195: /**
196: * Sets the onMouseDown JavaScript event for the HTML tbody tag.
197: *
198: * @param onMouseDown the onMouseDown event.
199: * @jsptagref.attributedescription The onMouseDown JavaScript event for the HTML tbody tag.
200: * @jsptagref.attributesyntaxvalue <i>string_onMouseDown</i>
201: * @netui:attribute required="false" rtexprvalue="true" description="The onMouseDown JavaScript event for the HTML tbody tag."
202: */
203: public void setOnMouseDown(String onMouseDown) {
204: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT,
205: HtmlConstants.ONMOUSEDOWN, onMouseDown);
206: }
207:
208: /**
209: * Sets the onMouseUp JavaScript event for the HTML tbody tag.
210: *
211: * @param onMouseUp the onMouseUp event.
212: * @jsptagref.attributedescription The onMouseUp JavaScript event for the HTML tbody tag.
213: * @jsptagref.attributesyntaxvalue <i>string_onMouseUp</i>
214: * @netui:attribute required="false" rtexprvalue="true" description="The onMouseUp JavaScript event for the HTML tbody tag."
215: */
216: public void setOnMouseUp(String onMouseUp) {
217: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT,
218: HtmlConstants.ONMOUSEUP, onMouseUp);
219: }
220:
221: /**
222: * Sets the onMouseMove JavaScript event for the HTML tbody tag.
223: *
224: * @param onMouseMove the onMouseMove event.
225: * @jsptagref.attributedescription The onMouseMove JavaScript event for the HTML tbody tag.
226: * @jsptagref.attributesyntaxvalue <i>string_onMouseMove</i>
227: * @netui:attribute required="false" rtexprvalue="true" description="The onMouseMove JavaScript event for the HTML tbody tag."
228: */
229: public void setOnMouseMove(String onMouseMove) {
230: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT,
231: HtmlConstants.ONMOUSEMOVE, onMouseMove);
232: }
233:
234: /**
235: * Sets the onMouseOut JavaScript event for the HTML tbody tag.
236: *
237: * @param onMouseOut the onMouseOut event.
238: * @jsptagref.attributedescription The onMouseOut JavaScript event for the HTML tbody tag.
239: * @jsptagref.attributesyntaxvalue <i>string_onMouseOut</i>
240: * @netui:attribute required="false" rtexprvalue="true" description="The onMouseOut JavaScript event for the HTML tbody tag."
241: */
242: public void setOnMouseOut(String onMouseOut) {
243: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT,
244: HtmlConstants.ONMOUSEOUT, onMouseOut);
245: }
246:
247: /**
248: * Sets the onMouseOver JavaScript event for the HTML tbody tag.
249: *
250: * @param onMouseOver the onMouseOver event.
251: * @jsptagref.attributedescription The onMouseOver JavaScript event for the HTML tbody tag.
252: * @jsptagref.attributesyntaxvalue <i>string_onMouseOver</i>
253: * @netui:attribute required="false" rtexprvalue="true" description="The onMouseOver JavaScript event for the HTML tbody tag."
254: */
255: public void setOnMouseOver(String onMouseOver) {
256: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_JAVASCRIPT,
257: HtmlConstants.ONMOUSEOVER, onMouseOver);
258: }
259:
260: /**
261: * Sets the style of the HTML tbody tag.
262: *
263: * @param style the style
264: * @jsptagref.attributedescription The style of the HTML tbody tag.
265: * @jsptagref.attributesyntaxvalue <i>string_style</i>
266: * @netui:attribute required="false" rtexprvalue="true" description="The style of the HTML tbody tag."
267: */
268: public void setStyle(String style) {
269: if ("".equals(style))
270: return;
271:
272: _tbodyTag.style = style;
273: }
274:
275: /**
276: * Sets the style class of the HTML tbody tag.
277: *
278: * @param styleClass the style class
279: * @jsptagref.attributedescription The style class of the HTML tbody tag.
280: * @jsptagref.attributesyntaxvalue <i>string_style_class</i>
281: * @netui:attribute required="false" rtexprvalue="true" description="The style class of the HTML tbody tag."
282: */
283: public void setStyleClass(String styleClass) {
284: if ("".equals(styleClass))
285: return;
286:
287: _tbodyTag.styleClass = styleClass;
288: }
289:
290: /**
291: * Sets the value of the title attribute for the HTML tbody tag.
292: *
293: * @param title the title
294: * @jsptagref.attributedescription The title for the HTML tbody tag
295: * @jsptagref.attributesyntaxvalue <i>string_title</i>
296: * @netui:attribute required="false" rtexprvalue="true" description="The title for the HTML tbody tag"
297: */
298: public void setTitle(String title) {
299: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_GENERAL,
300: HtmlConstants.TITLE, title);
301: }
302:
303: /**
304: * Sets the value of the horizontal alignment attribute of the HTML tbody tag.
305:
306: * @param align the horizontal alignment
307: * @jsptagref.attributedescription The horizontal alignment of the HTML tbody tag.
308: * @jsptagref.attributesyntaxvalue <i>string_align</i>
309: * @netui:attribute required="false" rtexprvalue="true" description="The cell's horizontal alignment of the HTML tbody tag."
310: */
311: public void setAlign(String align) {
312: /* todo: should this enforce left|center|right|justify|char as in the spec */
313: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_GENERAL,
314: HtmlConstants.ALIGN, align);
315: }
316:
317: /**
318: * Sets the value of the horizontal alignment character attribute of the HTML tbody tag.
319: *
320: * @param alignChar the horizontal alignment character
321: * @jsptagref.attributedescription The horizontal alignment character of the HTML tbody tag.
322: * @jsptagref.attributesyntaxvalue <i>string_alignChar</i>
323: * @netui:attribute required="false" rtexprvalue="true" description="The cell's horizontal alignment character of the HTML tbody tag."
324: */
325: public void setChar(String alignChar) {
326: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_GENERAL,
327: HtmlConstants.CHAR, alignChar);
328: }
329:
330: /**
331: * Sets the value of the horizontal alignment character offset attribute.
332: *
333: * @param alignCharOff
334: * @jsptagref.attributedescription The horizontal alignment character offset
335: * @jsptagref.attributesyntaxvalue <i>string_alignCharOff</i>
336: * @netui:attribute required="false" rtexprvalue="true" description="The cell's horizontal alignment character offset"
337: */
338: public void setCharoff(String alignCharOff) {
339: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_GENERAL,
340: HtmlConstants.CHAROFF, alignCharOff);
341: }
342:
343: /**
344: * Sets the value of the vertical alignment attribute of the HTML tbody tag.
345: *
346: * @param align the alignment
347: * @jsptagref.attributedescription The vertical alignment.
348: * @jsptagref.attributesyntaxvalue <i>string_align</i>
349: * @netui:attribute required="false" rtexprvalue="true" description="The vertical alignment of the HTML tbody tag"
350: */
351: public void setValign(String align) {
352: /* todo: should this enforce top|middle|bottom|baseline as in the spec */
353: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_GENERAL,
354: HtmlConstants.VALIGN, align);
355: }
356:
357: /**
358: * Sets the value of the language attribute of the HTML tbody tag.
359: *
360: * @param lang the language
361: * @jsptagref.attributedescription The language of the HTML tbody tag.
362: * @jsptagref.attributesyntaxvalue <i>string_lang</i>
363: * @netui:attribute required="false" rtexprvalue="true" description="The language of the HTML tbody tag."
364: */
365: public void setLang(String lang) {
366: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_GENERAL,
367: HtmlConstants.LANG, lang);
368: }
369:
370: /**
371: * Sets the value of the text direction attribute of the HTML tbody tag.
372: *
373: * @param dir the dir
374: * @jsptagref.attributedescription The text direction attribute of the HTML tbody tag.
375: * @jsptagref.attributesyntaxvalue <i>string_dir</i>
376: * @netui:attribute required="false" rtexprvalue="true" description="The text direction of the HTML tbody tag.
377: */
378: public void setDir(String dir) {
379: _tbodyTag.registerAttribute(AbstractHtmlState.ATTR_GENERAL,
380: HtmlConstants.DIR, dir);
381: }
382:
383: /**
384: * Set the name of the tagId for the HTML tbody tag.
385: *
386: * @param tagId - the the name of the tagId for the tbody tag.
387: * @jsptagref.attributedescription The tagId of the HTML tbody tag.
388: * @jsptagref.attributesyntaxvalue <i>string_tagId</i>
389: * @netui:attribute required="false" rtexprvalue="true"
390: * description="String value. Sets the id (or name) attribute of the HTML tbody tag."
391: */
392: public void setTagId(String tagId) throws JspException {
393: applyTagId(_tbodyTag, tagId);
394: }
395:
396: /**
397: * Set a boolean that enables / disables rendering HTML table rows by this tag. If the
398: * value is enabled, an HTML <tr> will be rendered when this tag renders its body. If
399: * the value is disabled, no <tr> tags will be rendered and the page author is responsible
400: * for maintaining the integrity of the HTML table.
401: * @jsptagref.attributedescription
402: * Set a boolean that enables / disables rendering HTML table rows by this tag. If the
403: * value is enabled, an HTML <tr> will be rendered when this tag renders its body. If
404: * the value is disabled, no <tr> tags will be rendered and the page author is responsible
405: * for maintaining the integrity of the HTML table.
406: * @jsptagref.attributesyntaxvalue <i>boolean_renderRow</i>
407: * @netui:attribute required="false" rtexprvalue="true"
408: * description="Boolean to enable / disable rendering HTML table row tags"
409: */
410: public void setRenderRow(boolean renderRow) {
411: _renderRow = renderRow;
412: }
413:
414: /**
415: * Render this tag. This method renders during the data grid's {@link DataGridTagModel#RENDER_STATE_GRID}
416: * state in order to add table rows to the beginning of a data grid's HTML table. If the data grid is rendering
417: * HTML row groups, this tag will output an HTML <tbody> tag. Then, if this tag is rendering
418: * a table row, it will produce an HTML <tr> tag. Then the content of the body will be rendered. If
419: * table row rendering is disabled, the page author is responsible for rendering the appropriate HTML
420: * table row tags as this tag renders inside of the HTML table opened by the data grid.
421: * @throws IOException
422: * @throws JspException when the {@link DataGridTagModel} can not be found in the {@link JspContext}
423: */
424: public void doTag() throws IOException, JspException {
425:
426: JspContext jspContext = getJspContext();
427: DataGridTagModel dataGridModel = DataGridUtil
428: .getDataGridTagModel(jspContext);
429: if (dataGridModel == null)
430: throw new JspException(
431: Bundle
432: .getErrorString("DataGridTags_MissingDataGridModel"));
433:
434: if (dataGridModel.getRenderState() == DataGridTagModel.RENDER_STATE_GRID) {
435:
436: StyleModel styleModel = dataGridModel.getStyleModel();
437: assert styleModel != null;
438:
439: TableRenderer tableRenderer = dataGridModel
440: .getTableRenderer();
441: assert tableRenderer != null;
442:
443: InternalStringBuilder content = new InternalStringBuilder();
444: AbstractRenderAppender appender = new StringBuilderRenderAppender(
445: content);
446: JspFragment fragment = getJspBody();
447:
448: if (dataGridModel.isRenderRowGroups())
449: tableRenderer.openTableBody(_tbodyTag, appender);
450:
451: HttpServletRequest request = JspUtil
452: .getRequest(getJspContext());
453: while (dataGridModel.hasNextDataItem()) {
454:
455: StringWriter sw = new StringWriter();
456:
457: /* first things first -- advance to the next data item */
458: dataGridModel.nextDataItem();
459:
460: fragment.invoke(sw);
461:
462: String trScript = null;
463: if (_renderRow) {
464: TrTag.State trState = new TrTag.State();
465: int index = dataGridModel.getCurrentIndex();
466: if (index % 2 == 0)
467: trState.styleClass = styleModel.getRowClass();
468: else
469: trState.styleClass = styleModel
470: .getAltRowClass();
471:
472: if (trState.id != null)
473: trScript = renderNameAndId(request, trState,
474: null);
475:
476: tableRenderer.openTableRow(trState, appender);
477: }
478:
479: content.append(sw.toString());
480:
481: if (_renderRow) {
482: tableRenderer.closeTableRow(appender);
483:
484: if (trScript != null)
485: appender.append(trScript);
486: }
487: }
488:
489: if (dataGridModel.isRenderRowGroups()) {
490: tableRenderer.closeTableBody(appender);
491:
492: String tbodyScript = null;
493: if (_tbodyTag.id != null) {
494: tbodyScript = renderNameAndId(request, _tbodyTag,
495: null);
496: }
497:
498: if (tbodyScript != null)
499: appender.append(tbodyScript);
500: }
501:
502: jspContext.getOut().write(content.toString());
503: }
504: }
505: }
|