• 沒有找到結果。

WAP Transformation Pattern

Chapter 6 Mobile Application Transformation

6.2 WAP Transformation Pattern

在本轉換樣式中,要說明的是:將PUML 文件轉換成 WML 程式碼的轉換規則,

以及將PGML 文件轉換成 WMLScript 程式碼的轉換規則。

以上兩種轉換規則合稱WAP Transformation Pattern。

使用PUML / PGML 所描述的行動應用程式,經過轉換成 WML / WMLScript 程 式碼之後,所有轉換出來的.wml 檔和.wmls 檔,以及相關的圖檔都放在同一個資 料夾下。

A. 在 PUML / PGML 中宣告的變數,其轉換之後的統一命名法則

在 WAP 中,所有的變數都是放在同一個 WMLBrowser context 中。所以,

為了避免在同一份PUML 文件中,在不同的 board 中出現相同的變數名,或 是在不同的 PGML 文件中,出現有相同名稱的全域變數。因為這些擁有相 同名稱的變數,在WAP 程式執行時,因為共用同一份 WMLBrowser context,

所以可能會產生邏輯語意不正確的情形。為了要避免這樣的狀況,就必須確 定每個要放在WMLBrowser context 中的變數名稱,必須是獨一無二的。方 法如下:

[轉換在 PUML 中宣告的變數]

在 PUML 文件中,變數的類型有兩種。一種是跟邏輯物件相關的變數,透 過<object>這個 element 的 attribute – name 來宣告,這類型的變數僅代表所 要使用的 WMLScript 檔(由相對應的 PGML 文件產生),所以不會被放到 WMLBrowser context 中,因此不額外做變數命名的處理。

另一種類型的變數,來自於使用者介面元件(UI component)的宣告描述,也 就是說,在PUML 中每描述一種使用者介面元件,都隱性地透過 attribute –

name

iname,宣告了屬於該使用者介面元件的變數。這些變數都會被放

到WMLBrowser context 中,所以必須做變數命名的處理。

整體而言,代表使用者介面元件的變數,在轉換之後的命名法則為:

Board name_UI component name_UI component attribute

Board name 是用來說明,該代表使用者介面元件的變數是位於哪個<board>

的element content 之中。UI component name 即是使用者介面元件的 attribute –

name 或 iname 的屬性值。在 PUML 中,使用者介面元件的 element 可以有

多種屬性(attribute),這些屬性和其屬性值可能也需要被當成變數和變數值,

放到WMLBrowser context 中,所以在上面的命名法則,也把 UI component attribute 加入,但不一定會使用到。經過這樣的命中法則之後,便可以確保 在WMLBrowser context 中的變數名稱都是唯一的。

以下舉例說明:

使用者介面 元件的宣告 描述

<picture name="demo" source="demo.jpg"

altText="Demo Image" align="center"/>

[

屬於

<board name="welcomeBoard">

element content]

轉換之後所 產生的變數 名稱

相對應的 WML 程式碼

<img src="demo.wbmp" alt="Demo Image"

align="middle"/>

備註 因為在WML 中,<img>的 attribute – src 這個 attribute 的 屬性值無法用變數來取代,也就是說

<img src=”$(imgSrc)”>是不允許的,所以執行於行動應用 程式背後的邏輯運算,無法在行動應用程式執行期間更改 圖片。因此,不對此使用者介面元件做任何的變數名稱的 處理。

使用者介面 元件的宣告 描述

<label name="hintMsg" showText="input bellow informaions: "/>

[

屬於

<board name="welcomeBoard">

element content]

轉換之後所 產生的變數 名稱

welcomeBoard_hintMsg_showText

相對應的 WML 程式碼

<b>$(welcomeBoard_hintMsg_showText)</b>

備註 因為<label>在使用者介面上的表現,是一串唯讀的文 字。而希望行動應用程式在執行期間,能透過後端的邏 輯運算,去更改其顯示在使用者介面上的文字,所以產 生這樣子的變數,用來儲存<label>的 attribute – showText 的屬性值。

使用者介面 元件的宣告 描述

<textnote name="userName" type="text" title="name:

"/>

[

屬於

<board name="welcomeBoard">

element content]

轉換之後所 產生的變數 名稱

1. welcomeBoard_userName 2. welcomeBoard_userName_title

相對應的 WML 程式碼

<p>$( welcomeBoard_userName_title)<input

name="welcomeBoard_userName" type="text"/></p>

備註 此使用者介面會產生兩種變數。第一種變數名稱直接會

被使用在WML 中的<input>的 attribute – name 中,也就 是在WML 中,用來記錄使用者輸入資料的變數。

此使用者介面元件可以透過attribute – title,來在使用者 介面的呈現上補充說明此使用者介面元件的描述,例如 輸入字串的提示。因為也希望這樣子的提示說明,也能 夠透過後端邏輯運算來做更改,因此也將它以變數的型 態存放在WMLBrowser context 中,所以產生第二種的變

數名稱,用來儲存<textnote>的 attribute – title 的屬性值。

使用者介面 元件的宣告 描述

<listpaper title="select one fruit:" iname="iFruit"

mode="single">

<item showText="apple"/>

</listpaper>

[

屬於

<board name="fruitBoard">

element content]

轉換之後所 產生的變數 名稱

1. fruitBoard_iFruit 2. fruitBoard_iFruit_title 3. fruitBoard_iFruit_item1 相對應的

WML 程式碼

<p>$( fruitBoard_iFruit_title)

<select iname="fruitBoard_iFruit" multiple="false">

<option>$(fruitBoard_iFruit_item1)</option>

</select></p>

備註 此使用者介面會產生三種變數。第一種變數名稱直接會

被使用在WML 中的<select>的 attribute – iname 中,也就 是在WML 中,用來記錄使用者選擇了哪些選項的變數。

此使用者介面元件可以透過attribute – title,來在使用者 介面的呈現上補充說明此使用者介面元件的描述,例如 選擇項目的提示。因為也希望這樣子的提示說明,也能 夠透過後端邏輯運算來做更改,因此也將它以變數的型 態存放在WMLBrowser context 中,所以產生第二種的變 數名稱,用來儲存<listpaper>的 attribute – title 的屬性值。

此使用者介面元件在最後的使用者介面的呈現上,是以 選單的型式出現。在行動應用程式執行期間,也希望能 夠透過後端邏輯運算的處理,來更改選單中選項的值,

所以產生第三種變數名稱。在<listpaper>中可能會有多個

<item>,所以每個<item>相對應的變數名稱都會加上編 號,例如第一個<item>對應的變數名稱為

xxx_xxx_item1,第二個為 xxx_xxx_item2,以此類推。

[轉換在 PGML 中宣告的變數]

為了避免在不同的PGML 文件中有相同名稱的全域變數產生,導致 WAP 行 動應用程式執行時,邏輯語意可能產生錯誤的情況,所以希望在轉換之後能 夠產生唯一的變數名稱。

在PGML 文件中,代表全域變數的變數名稱,在轉換之後的命名法則為:

Logic object name_global variable name

Logic object name 是來自於 PGML 文件的<object>這個 root element 中的 attribute – name,用來表示該全域變數是屬於哪個 PGML 文件,也就是用來 表示該全域變數是屬於哪個邏輯物件。global variable name 是來自於被宣告 成全域變數的<variable>的 attribute – name。經過這樣的命名法則之後,便 可以確保在WMLBrowser context 中的變數名稱都是唯一的。

以下舉例說明:

邏輯物件(PGML 文件)中的全域變數 相對應的 WMLScript 變數名稱 UserInfo.pgml 中的 userName UserInfo_userName

UserInfo.pgml 中的 userPassword UserInfo_userPassword FruitInfo.pgml 中的 choosed FruitInfo_choosed

... ……

B. PUML 轉成 WML 的轉換規則

接下來以條例式的方式,列出PUML 轉成 WML 的轉換規則。

z PUML 文件轉換成相對應的 WML 檔案之後,該 WML 檔的檔案名稱必 須跟PUML 文件的檔案名稱一樣,而副檔名由.puml 改成.wml。

例如:demo.puml Æ demo.wml

z 在轉換之後的 WML 程式碼中,不會使用<template>這個 element,來表 示每個WML card 中重覆、相同的邏輯,或是使用者介面元件。因為每 個使用者介面,都在PUML 的<board> element content 來各別描述。

z 在轉換之後的 WML 程式碼中,每個 card 中都不會有<prev/> (回上一頁) 這個task。因為在 PUML 中,使用<nextboard>這個 element 來控制全部 的使用者介面的瀏覽順序。所以在產生WML 程式碼時,全部使用<go>

這個element 來表示所要瀏覽的下個使用者介面。

因此,也不會有以下<template>產生:

<template>

<do type="prev" name="UIBack"><prev/></do>

</template>

因為在每個使用者介面都能回到上一頁的話,是不符合整個行動應用程 式的使用者介面瀏覽語意的。

z 在轉換之後的 WML 程式碼中,有兩個必要的<card> element,其 attribute – id 的屬性值分別是:

- @user-interfaceName_index。

(@user-interfaceName 是 指 相 對 應 的 PUML 文 件 中 ,

<user-interface>的 attribute – name 的屬性值。) - preSetting。

例如:

將DemoUI.puml (其 root element 即是<user-interface name=”DemoUI”>) 轉換成DemoUI.wml 後,WML 程式碼中會包含兩個 card。

一個是<card id=” DemoUI_index”>,另一個是<card id=” preSetting”>。

z attribute – id 的屬性值為@user-interfaceName_index 的 card,為第一個 必要的card,也就是.wml 檔中第一個出現的 card。負責設定 PUML 文 件中,所有用到的邏輯物件(global 或 local 的邏輯物件都要)的全部全域 變數。

Æ 利用每個邏輯物件對應的 WMLScript 檔的 globalVarDeclaration( ) function,來設定該邏輯物件的全域變數。

Æ 每個邏輯物件都有一個相對應的 inner card。利用一連串的 inner card 來完成所有邏輯物件的全域變數的設定 (chain of inner cards)。

[詳細作法如下:]

a) 每 個 邏 輯 物 件 (logic object) 都 有 一 個 相 對 應 的 inner card , 其 attribute – id 的命名規則為:

- 若在 PUML 中,為 global logic object 者,其對應的 inner card 的attribute – id 的屬性值 inner_@user-interfaceName_@name。

- 若在 PUML 中,為 local logic object 者,其對應的 inner card 的 attribute – id 的屬性值為 inner_@boardName_@name。

( @boardName 是該 local logic object 所在的<board>的

attribute – name 的屬性值。@name 是代表邏輯物件的<object>

attribute – name 的屬性值 )

b) 在轉換出來的 WML 程式碼中,inner card 出現的順序跟其相對應的 邏輯物件,出現在 PUML 文件中的順序一樣。而這一連串的 inner card,依照其出現順序來一一執行,因此稱呼這一連串的 inner card 為chain of inner cards。

c) attribute – id 的屬性值為@user-interfaceName_index 的 card, 沒有 onenterforward event, 但有 ontimer event (timer=1)。

- 若有 inner card 的話,則 ontimer event 觸發後,便要跑到第一個 inner card 來執行。

- 若無 inner card 的話,則 ontimer event 觸發後,便要跑到 attribute – id 的屬性值為 preSetting 的 card 來執行。

d) 每個 inner card 都會有兩個 event:

- 一個為 onenterforward event。此 event 觸發後,要執行相對應的 邏輯物件的相對應WMLScript 檔中的 globalVarDeclaration( )。

- 一個為 ontimer event。此 event 觸發後,要依照順序執行下一個 inner card。若無下一個 inner card 的話,則要執行 attribute – id 的屬性值為preSetting 的 card (timer= 1)。

z attribute – id 的屬性值為 preSetting 的 card 為第二個必要的 card。有兩 個event:onenterforward event 和 ontimer event:

a) 在onenterforward event 觸發後,要做的事為:設定出現在 PUML 文件中的,所有使用者介面元件(UI component)的相關變數。

b) 在ontimer event 觸發後,要執行 PUML 文件中所設定的,第一個 要呈現的使用者介面所對應到的card。

z 轉換成 WML / WMLScript 形式的行動應用程式後,在開始執行前必須 有一些前置作業,這些前置作業必需由一些特殊的cards 來完成。這些 cards 的執行順序為:attribute – id 的屬性值為@user-interfaceName_indexcard Æ chain of inner cards Æ attribute – id 的屬性值為 preSetting 的 card Æ PUML 文件中設定的第一個要呈現的使用者介面,所對應的 card。

z PUML 文件中,<action> element content 中的每一個 child element 都會 對應到一個 temp card,該 temp card 的 attribute – id 的屬性值為

@boardName_@actionName_temp[child position]

( @actionName 是該 child element 所在的<action>的 attribute – name 的 屬性質。[child position]的值,來自於該 child element 在<action>的 element content 中出現的順序。)

a) 在轉換出來的WML 程式碼中,temp card 出現的順序跟其相對應 的 child element,出現在<action>的 element content 中的順序一 樣。而這一連串的 temp card 會依照其出現的順序來一一執行,

a) 在轉換出來的WML 程式碼中,temp card 出現的順序跟其相對應 的 child element,出現在<action>的 element content 中的順序一 樣。而這一連串的 temp card 會依照其出現的順序來一一執行,