在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;
}
接下来的部分,相信你就可以轻松完成了:)