10. 如何在XPages裏實現典型的Notes權限控制?

(CSDN博客的bug不斷,因爲某些原因整理歷史文章時注意到這一篇在列表中消失了,搜索後發現有其他博主無引用地發表,在自己的博客上反倒被設爲私密了。取消私密設置並重新發布,文章的發表日期變爲當前日期,出現在文章列表的頂端。原來編輯文章頁面下方有保存和發佈兩個按鈕,印象中都不會修改文章原始的發表日期。在分類專欄裏尚可以手工排序,在全部文章列表裏則只會按修改日期排序。另外編輯摘要的功能也消失。對這些明顯的bug,也只能呵呵了。)

在傳統Notes開發中,我們經常通過隱藏公式實現對用戶權限的控制。在控制權限時,有時依據用戶名,有時是用戶所屬的羣組,還有時是其角色。這些信息都被包含在@UserNamesList的返回值裏,這樣我們就可以很方便地將它們與某個預定或由程序更新的域的內容作比較,實現對權限的靈活控制。@IsMember(@UserNamesList;FieldName)這樣的隱藏公式可以作爲一個樣例。

在XPages開發中,SSJS和Java Bean裏,我們如何實現這樣的效果?即獲得用戶的上述信息,並且與指定的身份信息比較。

首先我們想到上述公式在LotusScript 和Java中的對應項。Notes的API文檔有一個有用的特點,不同語言——公式、LotusScript、Java的某一頁面下方都有一個語言交叉參考的部分,會給出在其它語言中具有同樣或類似功能的函數。很不巧@UserNamesList頁面下沒有LotusScript對應項。Session有一個getUserNameList()的方法,一字母之差,返回的只有用戶名和可能的替代名。

那麼繼續使用公式可以嗎?IBM爲了方便Notes開發人員,減緩XPages的學習曲線,也使得他們的公式語言知識不至於成爲古董,允許在SSJS裏嵌入公式。但是這些公式只是原有公式的一部分,並不包含@UserNamesList。此路不通?且慢,我們還有幾乎萬能的Evaluate嘛。在LotusScript裏,我們可以用Evaluate函數計算@Functions的值;在SSJS和Java裏,我們有Session.evaluate()方法。實驗一下,在一個XPage裏,建一個計算文本,取值爲session.evaluate(@UserNamesList),結果成功返回。稍微需要注意的是,在SSJS中直接嵌入公式時,公式的寫法稍有變化,其中一點就是@Function需要寫成@Function()。而在用evaluate方法時,寫法還是@Function。

至此,問題似乎解決了。但是我不喜歡混合使用多種語言,在Java和SSJS裏夾雜@Functions雖然在功能上可行,但看上去“不美”。可否不用公式實現這些功能呢?

在SSJS的參考中,我們發現DirectoryUser對象可以獲得用戶名、角色和羣組(getDistinguishedName(), getRoles(),getGroups())。接下來在SSJS裏就比較容易完成剩下的部分了。爲了能在Java中實現,還需要費些力氣。我們先查出DirectoryUser的Java類型是接口com.ibm.designer.runtime.directory.DirectoryUser,在SSJS裏,它可以從全局對象context的getUser()獲得;這個context類型可查出是com.ibm.xsp.designer.context.XSPContext。如何獲得它的實例呢?我們只有求助於Java搜索功能,檢索返回類型爲com.ibm.xsp.designer.context.XSPContext的方法,最後在一個工具類中寫出如下的兩個方法:

     public static XSPContextgetContext(){

           javax.faces.context.FacesContext fc=javax.faces.context.FacesContext.getCurrentInstance();

           return com.ibm.xsp.designer.context.XSPContext.getXSPContext(fc);

     }

     public static Vector<</span>String> getUserNamesList(){

           Vector<</span>String> result=newVector<</span>String>();

           com.ibm.designer.runtime.directory.DirectoryUseruser=getContext().getUser();

           result.add(user.getDistinguishedName());

           result.addAll(user.getGroups());

           result.addAll(user.getRoles());

           return result;

     }
@IsMember()的功能,在Java中也不是現成的。因爲@UserNamesList和多值域返回的都是列表值,@IsMember()對兩個列表操作的結果是兩者只要有一個公共元素就返回真值。Java的Vector只能對是否包含單個元素或整個Collection做判斷。要判斷兩個Collection是否有交集,可以如此:
 
     public static booleanoverlaps(Collection coll1,Collection coll2){

         Set intersection = newHashSet(coll1);

         intersection.retainAll(newHashSet(coll2));

           return intersection.size()>0;

     }
接下來的部分,相信你就可以輕鬆完成了:)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章