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/下面的這些文件的代碼。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章