Liferay中portal-model-hints.xml文件的作用

Liferay中portal-model-hints.xml文件的作用

MSN群中Jacky Miao问到这个问题。自己也不了解,于是乘此机会读了一下源代码。

本文是从Word中拷贝的,因此没有修改标题编号。

1.1 基本情况

经过检查,在liferay项目中,共有两个类似文件:portal-ejb.jar中的portal-model-hints.xmlext-ejb.jar中的ext-model-hints.xml

文件的内容,是所有 model 对象的XML格式表述。如,ext项目中的相应内容:

<?xml version="1.0"?>

<model-hints>

       <model name="com.ext.portlet.reports.model.ReportsEntry">

              <field name="entryId" type="String" />

              <field name="companyId" type="String" />

              <field name="userId" type="String" />

              <field name="userName" type="String" />

              <field name="createDate" type="Date" />

              <field name="modifiedDate" type="Date" />

              <field name="name" type="String" />

       </model>

</model-hints>

Portal自带的portlet留言板中的一个model的定义为

       <model name="com.liferay.portlet.messageboards.model.MBCategory">

              <field name="categoryId" type="String" />

              <field name="groupId" type="String" />

              <field name="companyId" type="String" />

              <field name="userId" type="String" />

              <field name="userName" type="String" />

              <field name="createDate" type="Date" />

              <field name="modifiedDate" type="Date" />

              <field name="parentCategoryId" type="String" />

              <field name="name" type="String" />

              <field name="description" type="String">

                     <hint-collection name="TEXTAREA" />

              </field>

              <field name="lastPostDate" type="Date" />

       </model>

该文件跟ext-hbm.xml是类似但又各不相同的两个文件。Hbm文件是hibernate的描述文件,跟数据库是对应的。Model-hints主要是反映model的结构,不一定是数据库中的。

检查这个文件的内容,除了model的定义及其字段的定义之外,在一些字段上,会有一些hint信息,主要分为三类:

l         在文件最开始的hint-collection定义

<hint-collection name="BLOB">

       <hint name="max-length">2000000</hint>

</hint-collection>

<hint-collection name="TEXTAREA">

       <hint name="display-height">105</hint>

       <hint name="display-width">500</hint>

       <hint name="max-length">4000</hint>

</hint-collection>

l         每个model的缺省hints

<default-hints>

       <hint name="display-width">150</hint>

</default-hints>

l         一些字段的特殊hints。又分为两类: hint-collection hint 。其中,hint-collection是对前述collection的引用,hint是一些简单的定义。

<hint-collection name="TEXTAREA" />

<hint-collection name="BLOB" />

<hint name="show-time">false</hint>

<hint name="display-width">150</hint>

<hint name="max-length">200</hint>

 

1.2 文件的生成

该文件是由ServiceBuilder工具产生的。具体在com.liferay.portal.tools. ServiceBuilder中的函数_createModelHintsXML()中实现。

这个方法,是首先读出原来的文件内容,然后根据新的model ListXML内容进行修改。缺省情况下,自定义portlet中新建的model,添加到xml文件中没有任何hint信息。

这里有一个问题,根据需要,如果手工需要修改该文件,但下次重新ant build-service的时候,我们手工修改的内容是不是会被覆盖掉呢?根据前面对代码的阅读,我的初步判断是不会。同时,我又做了一下测试,验证了我的猜测。

1.3 文件的调用关系

在文件中如何应该该文件,也就是这个文件究竟有什么用?这是我们研究这个东西的目标。

文件的应用,主要是以下几个环节

1.3.1 文件portal.properties中定义

##

## Model Hints

##

 

#

# Input a list of comma delimited model hints configurations.

#

model.hints.configs=META-INF/portal-model-hints.xml,META-INF/ext-model-hints.xml

1.3.2 文件com.liferay.portal.util.PropsUtil中定义变量

// Model Hints

public static final String MODEL_HINTS_CONFIGS = "model.hints.configs";

1.3.3 文件com.liferay.portal.model.ModelHintsUtil中读取文件内容

1.3.3.1 代码分析

在构造函数中,核心代码

       private ModelHintsUtil() {

              _hintCollections = CollectionFactory.getHashMap();

              _defaultHints = CollectionFactory.getHashMap();

              _modelFields = CollectionFactory.getHashMap();

              ClassLoader classLoader = getClass().getClassLoader();

              String[] configs = StringUtil.split(

                     PropsUtil.get(PropsUtil.MODEL_HINTS_CONFIGS));

              for (int i = 0; i < configs.length; i++) {

                     _read(classLoader, configs[i]);

              }

       }

核心代码调用的是 函数_read(ClassLoader classLoader, String source),依次在分析一个model-hints.xml文件的内容。核心代码分析

String xml = StringUtil.read(classLoader, source);

首先读取hint-collection部分,并保存在全局Map _hintCollections

然后依次读取每一个model,并将每个modeldefault-hintsmodelnamekey,保存在Map_defaultHints中。然后在_modelFields中保存所有的field的定义,每个model的所有field放在一个Map中,并将该Mapmodelnamekey,保存在Map _modelFields中。

数据的保存,基本上等同于原来XML文件的格式,采用Map作为容器进行存放。记住三个关键的全局Map变量:

private Map _hintCollections;

private Map _defaultHints;

private Map _modelFields;

1.3.3.2 ModelHintsUtil的一些可用的方法

Map getDefaultHints(String model)

Element getFieldsEl(String model, String field)

String getType(String model, String field)

Map getHints(String model, String field)

1.3.3.3 检查哪些代码使用了ModelHintsUtil

结果发现只有一个java文件,那就是com.liferay.portal.tools. ServiceBuilder。呵呵,进入了循环。

我初步得出的结论是:model-hints.xml文件在运行过程中,好像没什么用。为了检验这一点,我尝试在运行环境中,把portal-ext.properties中的变量model.hints.configs设置为非法值,然后尝试运行liferay,看看有没有异常。将变量内容修改为:

model.hints.configs=META-INF/portal-model-hints-no.xml,META-INF/ext-model-hints-no.xml

重新启动liferay,简单尝试了几个功能。登录时没有问题,但在创建文件时发现了问题,forminput对象没有列出来;创建留言薄分类的时候,也是同样的问题。

1.4 JSP对文件model-hints.xml的调用情况

因为在java代码中没有发现问题,但是在执行的时候,一些forminput的显示出现了问题,可以认为,model-hints.xml应该是影响form端的ui的。

jsp中,以html\portlet\message_boards\edit_category.jsp 为例,input的代码如下,

<liferay-ui:input-field model="<%= MBCategory.class %>" bean="<%= category %>" field="description" />

在文件liferay-ui.tld中,input-field的定义为

       <tag>

              <name>input-field</name>

              <tagclass>com.liferay.taglib.ui.InputFieldTag</tagclass>

              <bodycontent>JSP</bodycontent>

       </tag>

检查文件com.liferay.taglib.ui.InputFieldTag.java,发现其实际调用的应该是JSP文件/html/taglib/ui/input_field/page.jsp

检查这个JSP的内容,原来在这里,核心代码如下:

String type = ModelHintsUtil.getType(model, field);

Map hints = ModelHintsUtil.getHints(model, field);

 

displayHeight = GetterUtil.getString((String)hints.get("display-height"), displayHeight);

displayWidth = GetterUtil.getString((String)hints.get("display-width"), displayWidth);

maxLength = GetterUtil.getString((String)hints.get("max-length"), maxLength);

upperCase = GetterUtil.getBoolean((String)hints.get("upper-case"), upperCase);

checkTab = GetterUtil.getBoolean((String)hints.get("check-tab"), checkTab);

 

<textarea class="form-text" <%= disabled ? "disabled" : "" %> id="<%= namespace %><%= field %>" name="<%= fieldParam %>" style="height: <%= displayHeight %>px; width: <%= displayWidth %>px;" wrap="soft" onKeyDown="<%= checkTab ? "checkTab(this); " : "" %> disableEsc();" onKeyPress="checkMaxLength(this, <%= maxLength %>);"><%= value %></textarea>

1.5 结论:model-hints.xm文件的作用

这些文件是用来在JSP中显示和处理FormInput参数的。在JSP中,使用<liferay-ui:input-field 的方法来输出input等,底层代码需要调用ModelHintsUtil获取该field的相关信息,并调整显示情况,以及一些js的处理。详细使用方法,需要查阅/html/taglib/ui/下面的这些文件的代码。 



你可能感兴趣的:(jsp,xml,UI,ejb,ext)