extremeComponents(ec)源码分析
eXtremeComponents(簡稱ec)是一系列提供高級顯示的開源JSP定制標簽,當前的包含的組件為eXtremeTable,用于以表形式顯示數據。
其本質是jsp的自定義標簽,抓住這一點就抓住了ec的本源。
1. Table定義
我們先看一下標簽的定義:extremComponents.tld,其中table的標簽定義如下:
<tag><name>table</name><tag-class>org.extremecomponents.table.tag.TableTag</tag-class><body-content>JSP</body-content><display-name>TableTag</display-name><description><![CDATA[The container which holds all the main table information. Will also hold global information if needed. The table tag is copied into the Table and encapsulated in the Model.]]></description><attribute><name>action</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The URI that will be called when the filter, sort and pagination is used.]]></description></attribute><attribute><name>autoIncludeParameters</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[Specify whether or not to automatically include the parameters, as hidden inputs, passed into the JSP.]]></description></attribute><attribute><name>border</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The table border attribute. The default is 0.]]></description></attribute><attribute><name>bufferView</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[Whether of not to buffer the view. Boolean value with the default being false.]]></description></attribute><attribute><name>cellpadding</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The table cellpadding attribute. The default is 0.]]></description></attribute><attribute><name>cellspacing</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The table cellspacing attribute. The default is 0.]]></description></attribute><attribute><name>filterable</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[Specify whether or not the table is filterable. Boolean value with the default being true.]]></description></attribute><attribute><name>filterRowsCallback</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[A fully qualified class name to a custom FilterRowsCallback implementation. Could also be a named type in the preferences. Used to filter the Collection of Beans or Collection of Maps.]]></description></attribute><attribute><name>form</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The reference to a surrounding form element.]]></description></attribute><attribute><name>imagePath</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The path to find the images. For example imagePath=/extremesite/images/*.png is saying look in the image directory for the .png images.]]></description></attribute><attribute><name>interceptor</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[A fully qualified class name to a custom InterceptTable implementation. Could also be a named type in the preferences. Used to add table attributes.]]></description></attribute><attribute><name>items</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[Reference the collection that will be retrieved.]]></description></attribute><attribute><name>locale</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The locale for this table. For example fr_FR is used for the French translation.]]></description></attribute><attribute><name>method</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[Used to invoke the table action using a POST or GET.]]></description></attribute><attribute><name>onInvokeAction</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The javascript that will be invoked when a table action enabled.]]></description></attribute><attribute><name>retrieveRowsCallback</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[A fully qualified class name to a custom RetrieveRowsCallback implementation. Could also be a named type in the preferences. Used to retrieve the Collection of Beans or Collection of Maps.]]></description></attribute><attribute><name>rowsDisplayed</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The number of rows to display in the table.]]></description></attribute><attribute><name>scope</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The scope (page, request, session, or application) to find the Collection of beans or Collection of Maps defined by the collection attribute.]]></description></attribute><attribute><name>showPagination</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[Specify whether or not the table should use pagination. Boolean value with the default being true.]]></description></attribute><attribute><name>showExports</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[Specify whether or not the table should use the exports. Boolean value with the default being true.]]></description></attribute><attribute><name>showStatusBar</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[Specify whether or not the table should use the status bar. Boolean value with the default being true.]]></description></attribute><attribute><name>showTitle</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[Specify whether or not to show the title. Boolean value with the default being true.]]></description></attribute><attribute><name>showTooltips</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[Specify whether or not to show the tooltips. Boolean value with the default being true.]]></description></attribute><attribute><name>sortRowsCallback</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[A fully qualified class name to a custom SortRowsCallback implementation. Could also be a named type in the preferences. Used to sort the Collection of Beans or Collection of Maps.]]></description></attribute><attribute><name>sortable</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[Specify whether or not the table is sortable. Boolean value with the default being true.]]></description></attribute><attribute><name>state</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The table state to use when returning to a table. Acceptable values are default, notifyToDefault, persist, notifyToPersist.]]></description></attribute><attribute><name>stateAttr</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The table attribute used to invoke the state change of the table.]]></description></attribute><attribute><name>style</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The css inline style sheet.]]></description></attribute><attribute><name>styleClass</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The css class style sheet.]]></description></attribute><attribute><name>tableId</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The unique identifier for the table.]]></description></attribute><attribute><name>theme</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The theme to style the table. The default is eXtremeTable.]]></description></attribute><attribute><name>title</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The title of the table. The title will display above the table.]]></description></attribute><attribute><name>var</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[The name of the variable to hold the current row bean.]]></description></attribute><attribute><name>view</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[Generates the output. The default is the HtmlView to generate the HTML. Also used by the exports to generate XLS-FO, POI, and CSV.]]></description></attribute><attribute><name>width</name><required>false</required><rtexprvalue>true</rtexprvalue><description><![CDATA[Width of the table.]]></description></attribute></tag>從上面我們可以看到,先定義了table標簽的實現類:org.extremecomponents.table.tag.TableTag,其作用是:
The container which holds all the main table information. Will also hold global information if needed. The table tag is copied into the Table and encapsulated in the Model.
一句話:保存table的信息及一些全局信息,通過table封裝到Model中。
然后定義了table的一些屬性,這些屬性和org.extremecomponents.table.bean.Table一致。
public class Table extends Attributes {private TableModel model;private String action;private Boolean autoIncludeParameters;private String border;private Boolean bufferView;private String cellpadding;private String cellspacing;private Boolean filterable;private String filterRowsCallback;private String form;private String imagePath;private String interceptor;private Object items;private String locale;private int maxRowsDisplayed;private int medianRowsDisplayed;private String method;private String onInvokeAction;private String retrieveRowsCallback;private int rowsDisplayed;private Boolean saveFilterSort;private String scope;private Boolean showExports;private Boolean showPagination;private Boolean showStatusBar;private Boolean showTitle;private Boolean showTooltips;private String sortRowsCallback;private Boolean sortable;private String state;private String stateAttr;private String style;private String styleClass;private String tableId;private String title;private String theme;private String var;private String view;private String width;public Table(TableModel model) {this.model = model;} // setter and getter }2. TableTag實現
我們來看一下TableTage如何實現table標簽?首先:TableTage繼承了TagSupport:
web容器執行自定義標簽的過程如下
初始化時調用setPageContent()方法,完了在調用setParent方法
2.1 ?web容器首先執行自定義標簽的開始標記,同時調用doStartTag方法。
2.2 ?如果doStartTag方法返回EVAL_BODY_INCLUDE,web容器在執行完標簽體的內容后,會調用標簽類得doAfterBody方法;
如果doStartTag方法返回SKIP_BODY,doAfterBody方法不會調用,web容器會直接調用標簽類得doEndTag方法
2.3 如果doAfterBody方法被調用,并且方法返回EVAL_BODY_AGIN,web容器會再次執行標簽體的內容;
如果doAfterBody方法返回SKIP_BODY,web容器會調用標簽類的doEndTag方法
2.4 如果doEndTag方法返回EVAL_PAGE,web容器會執行標簽后面的內容;
如果doEndTag方法返回SKIP_PAGE,web容器會忽略自定義標簽后面的內容
3. 深入追蹤到TableModel
? ? 在doAfterBody()方法中調用了TableModel的excute方法:
public Collection execute() throws Exception {//1. 查詢記錄Collection rows = TableModelUtils.retrieveRows(this);rows = new ArrayList(rows); // copy for thread safetythis.collectionOfBeans = rows;//2. 過濾和排序記錄rows = TableModelUtils.filterRows(this, rows);rows = TableModelUtils.sortRows(this, rows);this.collectionOfFilteredBeans = rows;// 3. 獲取記錄總數和pagesizeInteger totalRows = getTableHandler().getTotalRows();
int defaultRowsDisplayed = getTableHandler().getTable().getRowsDisplayed();if (totalRows != null) {
//4. 設置記錄總數和默認pagesize limit.setRowAttributes(totalRows.intValue(), defaultRowsDisplayed);} else {limit.setRowAttributes(rows.size(), defaultRowsDisplayed);}if (logger.isDebugEnabled()) {logger.debug(limit.toString());}//5. 獲取本次顯示的記錄rows = TableModelUtils.getCurrentRows(this, rows);this.collectionOfPageBeans = rows;//6. 視圖顯示 viewHandler.setView();return rows;}
4. 視圖顯示
? 默認定義了三種視圖模式:extremetable.properties
table.view.compact=org.extremecomponents.table.view.CompactView
table.view.limit=org.extremecomponents.table.view.LimitView
table.view.html=org.extremecomponents.table.view.HtmlView
調用抽象類的beforeBody方法:
調用HtmlView的beforeBodyInternal處理
protected void beforeBodyInternal(TableModel model) {toolbar(getHtmlBuilder(), getTableModel());getTableBuilder().tableStart();getTableBuilder().theadStart();statusBar(getHtmlBuilder(), getTableModel());getTableBuilder().filterRow();getTableBuilder().headerRow();getTableBuilder().theadEnd();getTableBuilder().tbodyStart();}工具欄:
protected void toolbar(HtmlBuilder html, TableModel model) {//layout 布局new DefaultToolbar(html, model).layout();}
左右布局格式:
public void layout() {if (!showLayout(model)) {return;}html.table(0).border("0").cellPadding("0").cellSpacing("0");Table table = model.getTableHandler().getTable();html.width(table.getWidth()).close();html.tr(1).close();// layout area leftcolumnLeft(html, model);// layout area right columnRight(html, model);html.trEnd(1);html.tableEnd(0);html.newline();}布局的實現:
protected void columnLeft(HtmlBuilder html, TableModel model) {html.td(2).close();new TableBuilder(html, model).title();html.tdEnd();}protected void columnRight(HtmlBuilder html, TableModel model) {boolean showPagination = BuilderUtils.showPagination(model);boolean showExports = BuilderUtils.showExports(model);ToolbarBuilder toolbarBuilder = new ToolbarBuilder(html, model);html.td(2).align("right").close();html.table(2).border("0").cellPadding("0").cellSpacing("1").styleClass(BuilderConstants.TOOLBAR_CSS).close();html.tr(3).close();if (showPagination) {html.td(4).close();toolbarBuilder.firstPageItemAsImage();html.tdEnd();html.td(4).close();toolbarBuilder.prevPageItemAsImage();html.tdEnd();html.td(4).close();toolbarBuilder.nextPageItemAsImage();html.tdEnd();html.td(4).close();toolbarBuilder.lastPageItemAsImage();html.tdEnd();html.td(4).close();toolbarBuilder.separator();html.tdEnd();html.td(4).style("width:20px").close();html.newline();html.tabs(4);toolbarBuilder.rowsDisplayedDroplist();html.img();html.src(BuilderUtils.getImage(model, BuilderConstants.TOOLBAR_ROWS_DISPLAYED_IMAGE));html.style("border:0");html.alt("Rows Displayed");html.xclose();html.tdEnd();if (showExports) {html.td(4).close();toolbarBuilder.separator();html.tdEnd();}}if (showExports) {Iterator iterator = model.getExportHandler().getExports().iterator();for (Iterator iter = iterator; iter.hasNext();) {html.td(4).close();Export export = (Export) iter.next();toolbarBuilder.exportItemAsImage(export);html.tdEnd();}}html.trEnd(3);html.tableEnd(2);html.newline();html.tabs(2);html.tdEnd();}狀態欄和工具欄類似,就不一一贅述了。
5. 動作觸發
以下一頁來理解ectable中是如何觸發事件的:
public void nextPageItemAsImage() {
ImageItem item = new ImageItem();
item.setTooltip(messages.getMessage(BuilderConstants.TOOLBAR_NEXT_PAGE_TOOLTIP));
item.setDisabledImage(BuilderUtils.getImage(model, BuilderConstants.TOOLBAR_NEXT_PAGE_DISABLED_IMAGE));
item.setImage(BuilderUtils.getImage(model, BuilderConstants.TOOLBAR_NEXT_PAGE_IMAGE));
item.setAlt(messages.getMessage(BuilderConstants.TOOLBAR_NEXT_PAGE_TEXT));
item.setStyle("border:0");
ToolbarItemUtils.buildNextPage(html, model, item);
}
下一頁的構建
public static void buildNextPage(HtmlBuilder html, TableModel model, ToolbarItem item) {int page = model.getLimit().getPage();String action = new TableActions(model).getPageAction(page + 1);item.setAction(action);int totalPages = BuilderUtils.getTotalPages(model);if (!BuilderUtils.isNextPageEnabled(page, totalPages)) {item.disabled(html);} else {item.enabled(html, model);}}觸發動作,js實現
public String getPageAction(int page) {StringBuffer action = new StringBuffer("javascript:");action.append(getClearedExportTableIdParameters());action.append(getFormParameter(TableConstants.PAGE, "" + page));action.append(getOnInvokeAction());return action.toString();}一個完整的table示例如下:
<table border="0" cellpadding="0" cellspacing="0" width="60%" ><tr><td><span class="title" >persons</span></td><td align="right" ><table border="0" cellpadding="0" cellspacing="1" class="toolbar" ><tr><td><img src="/address-book/public/images/table/firstPageDisabled.gif" style="border:0" alt="第一頁" /></td><td><img src="/address-book/public/images/table/prevPageDisabled.gif" style="border:0" alt="上一頁" /></td><td><img src="/address-book/public/images/table/nextPageDisabled.gif" style="border:0" alt="下一頁" /></td><td><img src="/address-book/public/images/table/lastPageDisabled.gif" style="border:0" alt="最后頁" /></td><td><img src="/address-book/public/images/table/separator.gif" style="border:0" alt="Separator" /></td><td style="width:20px" ><select name="ec_rd" onchange="javascript:document.forms.ec.ec_crd.value=this.options[this.selectedIndex].value;document.forms.ec.ec_p.value='1';document.forms.ec.setAttribute('action','/address-book/person/list');document.forms.ec.setAttribute('method','post');document.forms.ec.submit()" ><option value="5" selected="selected">5</option><option value="50" >50</option><option value="100" >100</option></select><img src="/address-book/public/images/table/rowsDisplayed.gif" style="border:0" alt="Rows Displayed" /></td></tr></table></td></tr> </table>6. 小結:
? ?eXtremeComponents為jsp開發table提供了比較好的支持,它的源碼可以作為學習jsp tag的一個很好示例,研究該源碼可以加深對jsp的理解,通過對上述源碼進行合適的擴展后可以作為組件庫使用。
參考文獻:
1.?http://liuna718-163-com.iteye.com/blog/1318991
2.?http://www.51cto.com/specbook/11/57761.htm
?
轉載于:https://www.cnblogs.com/davidwang456/p/4401742.html
總結
以上是生活随笔為你收集整理的extremeComponents(ec)源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ambiguous mapping fo
- 下一篇: 短信验证码、图形验证码、邮件验证的自动化