10. 如何在XPages里实现典型的Notes权限控制:@IsMember(@UserNamesList; FieldName)

在传统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;

     }
接下来的部分,相信你就可以轻松完成了:)

你可能感兴趣的:(10. 如何在XPages里实现典型的Notes权限控制:@IsMember(@UserNamesList; FieldName))