上次顺着显示页面BaseTemplate.jsp找到了处理该标记的java代码:
tag处理程序 | lib/sdrc_mwau/com/sdrc/_metaphase/wcc/mwau/form/tagext/FormGeneratorTag.java |
数据bean | |
显示bean 显示接口 | lib/sdrc_mwau/com/sdrc/metaphase/wcc/mwau/form/formbean/FormPresentationBean.java lib/sdrc_mwau/com/sdrc/_metaphase/wcc/mwau/form/renderer/WidgetRenderer.class HTMLWidgetRenderer.class |
先看标记
<sdrcMwau:formgenerator data="sdrcFormDataBean"
presentation="sdrcMODeLFormPresentationBean" name="TemplateForm"
method="POST" >
<%@ include file="/edsplm/mwau/HiddenParams.incjsp" %>
</sdrcMwau:formgenerator>
中的三个参数是如何被FormGeneratorTag接受的:
标记处理类在调用doStartTag()之前会事先将标记中所有属性填入类的本地变量。具体过程是调用一系列的setXXX方法。接着可以看到doStartTag()会使用findAttribute()获取该对象。
处理标记开始的方法:
public int doStartTag()
throws JspTagException
{
request = (HttpServletRequest)super.pageContext.getRequest();
context = (RequestContext)request.getAttribute("sdrcRequestContext");
errorLog = context.getApplicationLog();
serverLocale = context.getServerLocale();
userLocale = context.getUserLocale();
translate = context.getResourceLookup();
dataBean = (ModelEntityBean)super.pageContext.findAttribute(dataAttribute_);
if(dataBean == null)
throw new JspTagException(translate.getText("com.sdrc._metaphase.wcc.mwau.form.tagext.TextBundle", userLocale, "NO_DATA_BEAN"));
presBean = (FormPresentationBean)super.pageContext.findAttribute(presentationAttribute_);
if(presBean == null)
throw new JspTagException(translate.getText("com.sdrc._metaphase.wcc.mwau.form.tagext.TextBundle", userLocale, "NO_PRES_BEAN"));
widget_renderer = WidgetRendererFactory.createWidgetRenderer(dataBean, presBean, nameAttribute_, request);
if(genformAttribute_)
{
bodyOutput.append("<FORM NAME=/"");
bodyOutput.append(nameAttribute_);
bodyOutput.append("/" ");
if(methodAttribute_ != null && methodAttribute_.length() > 0)
{
bodyOutput.append(" METHOD=/"");
bodyOutput.append(methodAttribute_);
bodyOutput.append("/" ");
}
if(enctypeAttribute_ != null && enctypeAttribute_.length() > 0)
{
bodyOutput.append(" ENCTYPE=/"");
bodyOutput.append(enctypeAttribute_);
bodyOutput.append("/" ");
}
if(actionAttribute_ != null && actionAttribute_.length() > 0)
{
bodyOutput.append(" ACTION=/"");
bodyOutput.append(actionAttribute_);
bodyOutput.append("/" ");
}
bodyOutput.append(">/r/n");
}
bodyOutput.append(widget_renderer.getAdditionalScript());
bodyOutput.append("/r/n<TABLE>");//输出表格元素的开头
buildInit();
buildTable();
bodyOutput.append("</TABLE>/r/n");//输出表格元素的结尾
return 2;
}
红色部分就是在窗体上显示数据的一些痕迹
再看这两个被调用的方法:
protected void buildInit()
{
columnCount = presBean.elementCount();
}
protected void buildTable()
{
for(int i_row = 0; i_row < columnCount; i_row++)
{
boolean is_full_table_column = false;
String column_id = presBean.getElementId(i_row);
String full_table_parent_name = presBean.getAttribute(column_id, "ParentAttrName");
if(full_table_parent_name != null && full_table_parent_name.length() > 0)
is_full_table_column = true;
if(!is_full_table_column)
{
bodyOutput.append("<TR>/r/n");
if(presBean.isHiddenField(column_id))
buildHiddenField(column_id);
else
if(dataBean.isOutput(column_id) || isFullTableParentOutput && buildingFullTableColumn)
buildReadOnlyField(column_id);
else
buildEditableField(column_id);
bodyOutput.append("</TR>/r/n");
}
}
}
先看紫色的三个函数,分别对应于页面上的三种文本1.隐藏的2.普通文字3.输入框
protected void addPrompt(String column_id)
{
if(!presBean.isHiddenField(column_id) && !presBean.isFullTableColumn(column_id, null))
{
bodyOutput.append("<TD CLASS=/"input-label/" VALIGN=/"top/">");
bodyOutput.append(widget_renderer.getPrompt(column_id));
bodyOutput.append("</TD>/r/n");
}
}
private void buildEditableField(String column_id)
{
addPrompt(column_id);//就是上面的方法,针对可见的文字添加一个td
addRequiredIndicator(column_id);
bodyOutput.append("<TD>");
String editable_field = widget_renderer.getEditableField(column_id);
bodyOutput.append(editable_field);
addValidationMsg(column_id);
bodyOutput.append("</TD>/r/n");
}
private void buildHiddenField(String column_id)
{
String hidden_value = widget_renderer.getHiddenField(column_id);
bodyOutput.append(hidden_value);
}
private void buildReadOnlyField(String column_id)
{
addPrompt(column_id);
bodyOutput.append("<TD></TD>/r/n");
bodyOutput.append("<TD CLASS=/"input-body/">");
String readonly_field = widget_renderer.getReadOnlyField(column_id);
bodyOutput.append(readonly_field);
bodyOutput.append("</TD>/r/n");
}
上面三个函数的区别是很明显的,分别调用了三个不同的方法来获取数据字符串:getEditableField()、getHiddenField()、getReadOnlyField()。而后相同的部分是三者都调用了bodyOutput.append()把获得的数据字符串输出到页面。不同的是“隐藏文本”没有表格边框,否则不就显示了一个空的单元格?可编辑的文本多了一个addRequiredIndicator()调用以及addValidationMsg()检验。
下面让我们看一下这两个函数
protected void addRequiredIndicator(String column_id)
{
if(presBean.isCheckBox(column_id) && !presBean.isFullTableColumn(column_id, null))
bodyOutput.append("<TD> </TD>/r/n");
else
if(!presBean.isHiddenField(column_id) && !presBean.isFullTableColumn(column_id, null))
{
bodyOutput.append("<TD VALIGN=/"top/">");
bodyOutput.append(widget_renderer.getRequiredIndicator(column_id));
bodyOutput.append("</TD>/r/n");
}
}
protected void addValidationMsg(String column_id)
{
if(dataBean.isInError(column_id) && !presBean.isFullTable(column_id))
bodyOutput.append(widget_renderer.getValidationErrorMessage(column_id));
}
注意有两个对象在这里起了很重要的作用:presBean和widget_renderer
protected FormPresentationBean presBean;(在FormPresentationBean.class)
protected WidgetRenderer widget_renderer;(接口在WidgetRenderer.class中声明,在HTMLWidgetRenderer.class中实现)