李深圳 嚴(yán) 悍 戴 楠 卓勤政
(南京理工大學(xué)計(jì)算機(jī)科學(xué)與工程學(xué)院 南京 210094)
復(fù)雜語境下Web動態(tài)頁面分層重構(gòu)方法研究?
李深圳 嚴(yán) 悍 戴 楠 卓勤政
(南京理工大學(xué)計(jì)算機(jī)科學(xué)與工程學(xué)院 南京 210094)
針對復(fù)雜語境下Web語境敏感頁面的頁面冗余問題,論文分析了傳統(tǒng)設(shè)計(jì)中頁面設(shè)計(jì)及在動態(tài)控制方面的不足,基于COP提出一種動態(tài)的基于語境為中心的層槽頁面(LSP,Layer-Slot Page)語法,給出LSP頁面實(shí)現(xiàn)原理。通過自定義語境表現(xiàn)層標(biāo)簽實(shí)現(xiàn)動態(tài)頁面中語境約束的細(xì)粒度描述,并驅(qū)動Drools規(guī)則引擎計(jì)算規(guī)則文件,激活LSP分層信息。最后通過實(shí)例驗(yàn)證該重構(gòu)方案安全有效,具備語境變化的動態(tài)適應(yīng)能力,支持細(xì)粒度的安全訪問控制。
語境敏感;LSP;Web重構(gòu);訪問控制
在Web工作流系統(tǒng)中,隨著軟件的不斷演化,頁面動態(tài)性要求逐漸提高,使得業(yè)務(wù)邏輯判斷大量擴(kuò)散至Web頁面中。在這種以頁面元素為中心的傳統(tǒng)設(shè)計(jì)方法中,密集而復(fù)雜的語境條件作用于多個頁面元素中,使得表現(xiàn)層的語境描述低效而極易出錯,同時語境信息散落在多個頁面中,導(dǎo)致元素及其語境約束條件大量冗余。
為了解決這一問題,本文嘗試基于已有的頁面元素標(biāo)簽語法基礎(chǔ)上,引入COP(Context-Oriented Programming)[1]中的分層變化,提取動態(tài)頁面中的細(xì)粒度語境約束,通過Drools規(guī)則引擎[2]和自定義語境表現(xiàn)層標(biāo)簽,驅(qū)動規(guī)則引擎執(zhí)行語境約束條件,實(shí)現(xiàn)一種基于定制標(biāo)簽的動態(tài)頁面分層重構(gòu)方案。
目前的Web頁面設(shè)計(jì)方案中,大多仍然采用面向以元素為中心的頁面設(shè)計(jì)方式,對一個受控元素需將所有相關(guān)條件完整描述,并描述各種條件所對應(yīng)的不同變化,這導(dǎo)致頁面上相同或相似的約束條件散落在多個元素之上。
不同于普通業(yè)務(wù)代碼,Web動態(tài)頁面中的語境約束著業(yè)務(wù)無關(guān)的頁面元素,導(dǎo)致語境約束和元素緊耦合在一起,而元素可能出現(xiàn)在頁面不同的位置,文獻(xiàn)[3]中稱之為語境敏感。傳統(tǒng)的JSP/Struts2與后臺業(yè)務(wù)處理共同協(xié)作計(jì)算語境約束,雖然可以實(shí)現(xiàn)頁面元素的動態(tài)控制,但是具有以下幾個問題:
1)元素冗余。不同語境條件作用于同一頁面元素甚至頁面,將會導(dǎo)致頁面元素在不同位置多次出現(xiàn)。
2)語境約束的計(jì)算冗余。由于頁面設(shè)計(jì)以元素為中心,當(dāng)同一語境作用于不同位置的元素時,語境約束的計(jì)算將會重復(fù)。對于遞進(jìn)式的語境約束,傳統(tǒng)方式常常難以有效利用前序語境結(jié)果。
3)語境約束與業(yè)務(wù)邏輯耦合。當(dāng)發(fā)生語境約束變更時,需要同時修改頁面和服務(wù)器端代碼文件并重啟服務(wù)器才能使更改生效。
4)難以維持訪問控制策略的一致性。在語境條件約束下,受控元素遵從細(xì)粒度的主動式訪問控制[4]策略實(shí)現(xiàn)。多角色在同一頁面的共存,顯著提高了語境約束的復(fù)雜度,將難以確保不同角色在正確的權(quán)限范圍內(nèi)訪問系統(tǒng)。
同時EVP原則[5]要求良性系統(tǒng)封裝可變性,將語境條件分離并獨(dú)立封裝。因此本文在已有的頁面元素標(biāo)簽語法基礎(chǔ)上,引入COP編程風(fēng)格,借助于自定義標(biāo)簽提取動態(tài)頁面中的語境約束,進(jìn)行獨(dú)立封裝并細(xì)粒度描述,驅(qū)動Drools執(zhí)行引擎計(jì)算語境約束條件,實(shí)現(xiàn)一種基于定制語境標(biāo)簽的動態(tài)頁面分層重構(gòu)方案。
3.1 面向語境編程
Context-Oriented Programming基于語境為中心,執(zhí)行器根據(jù)語境動態(tài)地改變對象行為,實(shí)現(xiàn)語境化的模塊結(jié)構(gòu),解決復(fù)雜語境下不斷變化導(dǎo)致難以維護(hù)的問題。目前,最具代表性的COP語言(如:ContextL[6],ContextS[7],ContextJ[8]),普遍采用以層-槽結(jié)構(gòu)描述行為變化的方式,在運(yùn)行時根據(jù)語境條件激活相應(yīng)的層,使層的變化作用于對象行為,最后執(zhí)行該對象行為,具體的分為行為變化(Behavioral variations)、層(Layers)、激活(Activation)、語境(Context)、作用范圍(Scope)五個特性[1]。 圖1描述了COP語言的基本實(shí)現(xiàn)原理。
3.2 層槽頁面(LSP)
基于COP編程模型,本文實(shí)現(xiàn)一種動態(tài)的基于語境的層槽頁面(LSP,Layer-Slot Page),層槽頁面結(jié)構(gòu)由共有元素和層槽信息組成。引入層槽結(jié)構(gòu)將傳統(tǒng)的以元素為中心轉(zhuǎn)變?yōu)橐哉Z境條件為中心,使具有相同語境約束條件的元素變化封裝到同一層中,不同語境約束條件封裝在不同層,運(yùn)行時根據(jù)語境條件激活不同的層級變化。
圖1 語境分層激活示意圖
1)層(Layer)用來表示特定語境條件下多個共有元素的行為變化,一旦激活其將被作用于共有元素,一個層中通常包含多個槽(Slot)。層在本文頁面設(shè)計(jì)中的定義如下:
<c:level constraints=“constraint 1,constraint 2,…”>
<li>E,P1=V1,P2=V2,…</li>
……</c:level>
2)槽(Slot)表示一個或一類元素的一組變化。采用變長三元組<E,P,V>來描述一個槽結(jié)構(gòu),具體含義如下:
E:表示頁面元素Element,即變化所作用的元素。共有元素中的某個元素的標(biāo)識id或class(以class:開頭表示指定標(biāo)識為class屬性),用于確定要發(fā)生變化的一個或一組元素。
P:表示屬性Property,即元素E的某個屬性名。例如,按鈕有value屬性和disabled等屬性。
V:表示屬性值Value,一個值,可以是單值或多值,表示增加或修改元素性質(zhì)的結(jié)果。例如按鈕的class屬性值可以是“class1”,也可以是“class1 class2”。也可以為NULL,表示刪除當(dāng)前屬性。
一個槽可描述一個元素的一個或多個屬性的增加或修改,但應(yīng)避免同一層下多個槽對同一元素的同一屬性進(jìn)行改變。例如同時需要在class為button1按鈕上的value屬性和disabled屬性上變化,應(yīng)表示如下:
<li>class:button1,
value=click me,disabled=disabled</li>
3)根據(jù)上述層槽原理,LSP頁面分層實(shí)施組件部分采用客戶端實(shí)現(xiàn),對激活槽的行為變化進(jìn)行解釋并實(shí)施,算法原理如下:
ACTIVATION-ALGORITHM
1 for each layer:L
2 for each slot:<E,P1=V1,…,Pi=Vi,…>
3 for each variation:<E,Pi=Vi>
4 if Vi==NULL
5 E.Pi=NULL;
6 else
7 E.Pi=Vi;
8 end if
9 end for
10 end for
11 remove layer L description
12 end for
實(shí)施組件的作用過程在共有頁面元素渲染完之后,以及所有頁面資源加載完之前進(jìn)行。變化實(shí)施組件采用 JavaScript[9]語言編程實(shí)現(xiàn)。
基于Drools規(guī)則引擎收集語境信息,實(shí)現(xiàn)語境約束在規(guī)則文件中的可配置化,依據(jù)細(xì)粒度的語境執(zhí)行結(jié)果激活不同的層,其實(shí)現(xiàn)原理如圖2。
圖2 基于Drools驅(qū)動的頁面分層示意圖
4.1 規(guī)則計(jì)算
Drools是一個基于Java的業(yè)務(wù)邏輯計(jì)算引擎,通常將復(fù)雜的業(yè)務(wù)邏輯封裝在后綴名為drl的規(guī)則文件中,規(guī)則文件是純文本文件,支持運(yùn)行時動態(tài)修改,Drools支持?jǐn)?shù)據(jù)傳遞,實(shí)現(xiàn)語境敏感的邏輯計(jì)算,并且作為結(jié)果返回,該數(shù)據(jù)對象通常被稱作Fact[10]。
本文規(guī)則引擎由定制標(biāo)簽context的標(biāo)簽處理方法驅(qū)動,并執(zhí)行規(guī)則文件。規(guī)則文件在運(yùn)行時可以按需動態(tài)執(zhí)行,因此采用規(guī)則文件封裝語境變化,可以支持語境的動態(tài)配置,而無需重啟服務(wù)器。
規(guī)則文件中規(guī)則一般按優(yōu)先級別順序執(zhí)行,但是前后規(guī)則之間仍然存在多種關(guān)系,包括:
1)遞進(jìn):前序規(guī)則的執(zhí)行條件是后序規(guī)則執(zhí)行條件的必要條件;
2)制約:前序規(guī)則的執(zhí)行結(jié)果影響后序規(guī)則的執(zhí)行條件;
3)互斥:前序規(guī)則的執(zhí)行條件與后序規(guī)則的執(zhí)行條件互斥。
規(guī)則與動態(tài)頁面中的語境約束條件具備同質(zhì)性,往往一個語境約束行為可以描述為一個規(guī)則,而規(guī)則名稱采用自然語言命名。為了支持語境約束的細(xì)粒度描述,并且保持與規(guī)則文件的一致性,本文約定在動態(tài)頁面中采用一個詞匯命名一個語境約束單元,并為之實(shí)現(xiàn)一個同名規(guī)則。于是語境約束的計(jì)算可以實(shí)現(xiàn)規(guī)則文件配置化處理,同時規(guī)則計(jì)算方式消除了冗余的語境約束條件。
4.2 定制標(biāo)簽及標(biāo)簽處理
本文采用兩種自定義語境標(biāo)簽用于驅(qū)動規(guī)則引擎的執(zhí)行,實(shí)現(xiàn)層槽信息的動態(tài)渲染,同時該框架實(shí)現(xiàn)包含定制標(biāo)簽、標(biāo)簽處理類、規(guī)則計(jì)算模塊、Fact語境對象和結(jié)果緩存。Web語境標(biāo)簽驅(qū)動分層原理如圖3所示。
圖3 Web語境標(biāo)簽驅(qū)動分層框架
其中,語境計(jì)算標(biāo)簽context作為level標(biāo)簽的父標(biāo)簽,定義了ruleFiles屬性用于指定待執(zhí)行規(guī)則文件,多個規(guī)則文件之間以逗號分隔。context標(biāo)簽在后臺標(biāo)簽處理方法中驅(qū)動執(zhí)行引擎,并將執(zhí)行結(jié)果保存在當(dāng)前請求下的結(jié)果緩存中。level標(biāo)簽通過指定constraints屬性,查詢當(dāng)前層的細(xì)粒度語境約束結(jié)果,并控制層槽信息的動態(tài)生成。細(xì)粒度語境約束的描述可以采用規(guī)則文件名形式,以“!”符號取反,“,”表示細(xì)粒度語境約束間的邏輯與關(guān)系。假設(shè)標(biāo)簽前綴為c,則上述定制標(biāo)簽的具體使用語法如下:
<c:context ruleFiles=“file1.drl,file2.drl,…”>
<c:level constraints=“rule1,rule2,…”>
<li>E,P1=V1,…,Pi=Vi,…</li>
…
</c:level>
…
</c:context>
標(biāo)簽處理過程中,規(guī)則文件的執(zhí)行往往需要傳入一些當(dāng)前請求下的語境信息,這些信息定義以<key,value>鍵值對形式封裝在 ContextBean對象中,ContextBean對象作為Fact對象傳入規(guī)則引擎的執(zhí)行內(nèi)存,并以RequestCache對象作為結(jié)果緩存,記錄最終執(zhí)行結(jié)果。
在線派工服務(wù)系統(tǒng)是一個在線醫(yī)療養(yǎng)老服務(wù)平臺,目的是為線下醫(yī)療服務(wù)機(jī)構(gòu)提供在線服務(wù)解決方案,是一個多角色多狀態(tài)復(fù)雜Web系統(tǒng),由客戶、醫(yī)療機(jī)構(gòu)管理員和醫(yī)療服務(wù)人員共同完成派工服務(wù),系統(tǒng)中將一次派工服務(wù)的基本憑證定義為派工單。
5.1 應(yīng)用
在線醫(yī)療派工服務(wù)系統(tǒng),提供了對派工單的在線協(xié)同處理。該流程需要客戶、醫(yī)療機(jī)構(gòu)管理員以及醫(yī)療服務(wù)人員協(xié)作完成。一個派工單處理頁面中尾部有一個處理按鈕,針對派工單的不同階段,分別對應(yīng)不同的操作。具體的操作條件分別為
1)未派工??蛻籼峤环?wù)請求后,機(jī)構(gòu)管理員可以看見未處理的服務(wù)請求信息,按鈕狀態(tài)應(yīng)為“派工”。
2)已派工。機(jī)構(gòu)管理員對一個訂單執(zhí)行派工操作后,服務(wù)人員將可以看見更新后的訂單信息,按鈕狀態(tài)應(yīng)為“接單”。
3)待確認(rèn)。服務(wù)人員接受派工服務(wù),當(dāng)前訂單即更新為待確認(rèn)狀態(tài),等待客戶處理,按鈕狀態(tài)應(yīng)為“確認(rèn)”。
一個標(biāo)準(zhǔn)派工單服務(wù)活動如圖4所示。
圖4 訂單服務(wù)活動圖
上述派工單服務(wù)流程,每一個訂單的服務(wù)狀態(tài)下都蘊(yùn)含一個復(fù)雜語境約束,在現(xiàn)行頁面方案中,多數(shù)仍采用多頁面多元素方式處理,所以至少需要“派工”、“接單”、“確認(rèn)”三個按鈕協(xié)作完成本次流程。本文采用LSP客戶端頁面,針對上述流程僅需采用同一頁面,設(shè)計(jì)一個共有按鈕元素,然后在語境約束滿足情況下,實(shí)施組件激活對該元素進(jìn)行的渲染。共有按鈕設(shè)計(jì)如下:
<input id=“confirmBtn ”type=“button”/>
動態(tài)LSP頁面要求運(yùn)行時激活層級變化,需要使用context標(biāo)簽和level標(biāo)簽,描述并驅(qū)動語境約束執(zhí)行,本文將語境進(jìn)行細(xì)粒度描述,并在規(guī)則文件中定義對應(yīng)的規(guī)則。
<c:context ruleFiles=“authority.drl,orderFlow.drl”>
<c:level constraints=“admin,!dispatched”>
<li>confirmBtn,value=派工</li>
</c:level>
<c:level constraints=“servant,dispatched,!solved”>
<li>confirmBtn,value=接單</li>
</c:level>
<c:level constraints=“client,solved ,!confirmed ”>
<li>confirmBtn,value=確認(rèn)</li>
</c:level>
</c:context>
其中兩個規(guī)則文件authority.drl,orderFlow.drl分別對應(yīng)角色訪問控制規(guī)則和訂單狀態(tài)規(guī)則,其中角色訪問控制規(guī)則用于判定客戶角色對當(dāng)前操作的有效性,定義了ADMIN,SERVANT,CLIENT三個規(guī)則。其中ADMIN規(guī)則如下:
rule“ADMIN”
when
$contextBean :ContextBean()
eval(roleValidation($contextBean))
then
ServletRequest request
=(ServletRequest)$contextBean.get(“request”);
RequestCache resultCache=(RequestCache)
request.getAttribute(“resultCache”);
resultCache.put(“admin”,Boolean.TRUE);
end
規(guī)則計(jì)算完成后,level標(biāo)簽處理方法便可以依據(jù)結(jié)果緩存中的admin屬性判定“admin”約束是否成立。
訂單狀態(tài)規(guī)則中定義了dispatched,accepted,confirmed三個規(guī)則,對應(yīng)請求單的狀態(tài)判斷。其中
dispatched規(guī)則描述如下:
rule“DISPATCHED”
when
$contextBean :ContextBean()
eval(getRequest($contextBean)
.getDispatchTime()!=null)
then
ServletRequest request
=(ServletRequest)$contextBean.get(“request”);
RequestCache resultCache=(RequestCache)
request.getAttribute(“resultCache”);
resultCache.put(“dispatched”,Boolean.TRUE);
end
依據(jù)這些規(guī)則計(jì)算,最終level標(biāo)簽處理可以動態(tài)控制層級信息,實(shí)現(xiàn)按鈕狀態(tài)與語境約束間的一致性,減少了按鈕元素的冗余,同時采用獨(dú)立的規(guī)則文件分離了語境約束,實(shí)現(xiàn)復(fù)雜語境下的語境約束和頁面元素的低冗余重構(gòu)。
5.2 分析與比較
本文基于COP編程思想,實(shí)現(xiàn)動態(tài)頁面的一種分層重構(gòu)方案。本方案適用于Web語境敏感頁面,支持復(fù)雜語境約束的細(xì)粒度描述,支持動態(tài)配置。
與傳統(tǒng)的Jsp/Struts2頁面比較,本文所提方案具有以下特點(diǎn):
1)封裝變化與可擴(kuò)展。重構(gòu)后,將Web敏感頁面中的以元素為中心轉(zhuǎn)移到以語境約束為中心,封裝語境條件的同時,消除由語境約束變化造成的頁面元素冗余。
2)語境約束松耦合。語境約束條件不斷變化,并且相互之間存在緊耦合的依賴關(guān)系,本文將語境約束細(xì)粒度描述,并采用規(guī)則式組織,使得各LSP層間的語境約束松耦和,編寫LSP層時,僅依賴于當(dāng)前層所受語境約束。
3)訪問控制策略分離。采用Drools規(guī)則文件組織語境約束條件,易于實(shí)現(xiàn)訪問控制級別的語境約束共享,如建立一個authority.drl,其中定義了各類角色規(guī)則。當(dāng)實(shí)施元素級別的細(xì)粒度訪問控制時,僅需配置authority.drl文件中的相應(yīng)角色的規(guī)則信息。易于維持訪問控制策略的一致性,確保系統(tǒng)安全性。
針對復(fù)雜的語境敏感的Web頁面,本文基于COP中的分層變化編程思想,提取動態(tài)頁面中的細(xì)粒度語境約束,通過Drools規(guī)則引擎和自定義語境表現(xiàn)層標(biāo)簽,驅(qū)動規(guī)則引擎執(zhí)行語境約束條件,實(shí)現(xiàn)一種基于定制語境標(biāo)簽的動態(tài)頁面分層重構(gòu)方案。該方案將散布在頁面中的語境約束條件轉(zhuǎn)移到規(guī)則文件中描述,支持語境變化的動態(tài)可配置,支持細(xì)粒度控制元素變化,同時在頁面中以語境約束為中心,激活LSP層槽變化,消除頁面元素及語境約束冗余。
本文方法適用于復(fù)雜Web語境敏感的頁面,包括:1)語境約束條件密集繁復(fù);2)語境約束與業(yè)務(wù)邏輯代碼耦合;3)需要大量元素級別的訪問控制。
[1]Hirschfeld R,Costanza P,Nierstrasz O.Context-oriented Programming[J].Journal of Object Technology,2015,7(3):125-151.
[2]Proctor M,Neale M,Lin P,et al.Drools documentation[EB/OL].http://www.drools.org/learn/documentation.html,2015-12-10.
[3]Gregory D.Towards a better understanding of context and context-awareness[J].Handheld and ubiquitous Computing.Berlin:Springer,2000:304-307.
[4]蔣明輝.基于動態(tài)語境實(shí)現(xiàn)主動式Web訪問控制[D].南京:南京理工大學(xué),2012:17-23.JIANG Minghui.The Implementation of Active Access Control based on Dynamic Context[D].Nanjing:Nanjing University of Science&Technology,2012:17-23.
[5]Meyer B.Object-oriented software construction[M].London:Prentice Hall,1988:53-64.
[6]Costanza P,Hirschfeldb R.Reflective layer activation in ContextL[J].Springer Verlag,2007:1280-1285.
[7]Hirschfeld R.Aspects-aspect-oriented programming with squeak[M].Objects,Components,Architectures,Services,and Applications for a Networked World.Springer Berlin Heidelberg,2003:216-232.
[8]Appeltauer M,Hirschfeld R,Haupt M,et al.ContextJ:Context-oriented programming with Java[J].Information and Media Technologies,2011,6(2):399-419.
[9]Keith J,Sambells J.DOM Scripting:Web Design with JavaScript and the Document Object Model[M].Apress,2010:7-44.
[10]Browne P.Drools JBoss rules 5.X developer's guide[M].Packt Publishing,2013:79-97.
Research on Refactoring Method of Web Dynamic Page Based on Complex Context
LI Shenzhen YAN Han DAI Nan ZHUO qinzheng
(School of Computer Science&Engineering,Nanjing University of Science&Technology,Nanjing 210094)
Considering complex context,for the problem of page redundancy in Web context-aware page,the traditional method of page design and the deficiency in dynamic control is analysed in this paper,and the COP as a reference to propose a dynamic Layer-Slot page syntax which is centered on context is taken,while given the working principle.Through the definition of the presentation layer label correlated with context,the context constraint fine-grained access control in dynamic page is achieved,then it drives the Drools engine to compute rule files and activate the LSP layer information.Finally,the security and efficiency of the refactoring method is validated,which has the ability to adapt with the changeable context and provides the fine-grained security access control.
context-aware,LSP,Web refactoring,access control
TP311
10.3969/j.issn.1672-9722.2017.11.029
Class Number TP311
2017年5月9日,
2017年6月11日
李深圳,男,碩士,研究方向:軟件工程與應(yīng)用。嚴(yán)悍,男,博士,副教授,研究方向:信息安全與軟件工程。
戴楠,男,碩士,研究方向:軟件工程與應(yīng)用。卓勤政,男,碩士,研究方向:軟件工程與應(yīng)用。