在用Java进行XPages开发时,有一些常见的基础性的任务。这些经常要做的事部分与在Lotus Notes客户端开发时遇到的相同,例如获得当前Session和数据库对象,但是达成的方法与用LotusScript截然不同;其它则是XPages开发环境特定的需求,比如获得当前com.ibm.xsp.designer.context.XSPContext和RequestMap对象(即RequestScope变量)。将这些频繁需要的任务以静态方法的形式写在一个工具类里是很好用的:
package starrow.xsp; import java.lang.reflect.Method; import java.util.*; import javax.faces.context.FacesContext; import starrow.AppException; import lotus.domino.*; import lotus.domino.local.NotesBase; import com.acme.tools.JSFUtil; import com.ibm.designer.runtime.directory.DirectoryUser; import com.ibm.xsp.component.UIViewRootEx2; import com.ibm.xsp.designer.context.XSPContext; import com.ibm.xsp.model.DataSource; import com.ibm.xsp.model.domino.DominoDocumentData; import com.ibm.xsp.model.domino.DominoUtils; import com.ibm.xsp.model.domino.wrapped.DominoDocument; @SuppressWarnings("unchecked") public class XSPUtil { public static Session getSession(){ //return (Session) JSFUtil.getVariableValue("session"); return DominoUtils.getCurrentSession(); } public static Session getSessionAsSigner(){ return (Session) JSFUtil.getVariableValue("sessionAsSigner"); } public static Database getDatabase() throws NotesException{ return getSession().getCurrentDatabase(); //return (Database) JSFUtil.getVariableValue("database"); } public static Database getDatabase(String dbPath) throws NotesException{ String server=getDatabase().getServer(); return getDatabase(server, dbPath); } public static Database getDatabase(String server, String dbPath) throws NotesException{ return getSession().getDatabase(server, dbPath); } public static XSPContext getContext(){ //return (XSPContext) JSFUtil.getVariableValue("context"); FacesContext fc=FacesContext.getCurrentInstance(); return XSPContext.getXSPContext(fc); } public static Document getCurrentDocument() throws Exception{ UIViewRootEx2 view=(UIViewRootEx2) FacesContext.getCurrentInstance().getViewRoot(); for (DataSource ds : view.getData()){ if (ds instanceof DominoDocumentData){ DominoDocumentData ddd=(DominoDocumentData) ds; DominoDocument dd=(DominoDocument) ddd.getDataObject(); return dd.getDocument(); } } throw new AppException("No document data source is found."); //return null; } public static DominoDocument getCurrentDominoDocument() throws Exception{ UIViewRootEx2 view=(UIViewRootEx2) FacesContext.getCurrentInstance().getViewRoot(); for (DataSource ds : view.getData()){ if (ds instanceof DominoDocumentData){ DominoDocumentData ddd=(DominoDocumentData) ds; return (DominoDocument) ddd.getDataObject(); } } throw new AppException("No document data source is found."); //return null; } public static Object[] getRoles(){ XSPContext context=XSPUtil.getContext(); List userRoles=context.getUser().getRoles(); return userRoles.toArray(); } public static boolean hasRoles(String[] roles){ XSPContext context=XSPUtil.getContext(); List userRoles=context.getUser().getRoles(); for (Object ur : userRoles){ for (String r : roles){ if (ur.toString().equals(r)){ return true; } } } return false; } public static boolean hasRole(String role){ String[] roles={role}; return hasRoles(roles); } //returns a Vector<String> containing the name, groups and roles of the current user. public static Vector<String> getUserNamesList() throws NotesException{ Vector<String> result=new Vector<String>(); DirectoryUser user=getContext().getUser(); //DirectoryUser.getFullName() returns the common name. //I can reproduce the issue in both 8.5.1-3. //For local preview, getFullName() returns Anonymous, getDistinguishedName() returns anonymous. result.add(getSession().getEffectiveUserName()); result.addAll(user.getGroups()); result.addAll(user.getRoles()); return result; } public static Map getRequestMap(){ return FacesContext.getCurrentInstance().getExternalContext().getRequestMap(); } public static void feedback(String msg){ getRequestMap().put("message", msg); } }
对这个工具类稍加说明:
feedback()将一个字符串消息传递到RequestMap里,以message键保存,供页面上的消息控件显示。此一约定的键和方法可被managed bean用于向前端反馈消息。
getContext()方法返回com.ibm.xsp.designer.context.XSPContext对象,XSPContext作为对FacesContext的扩展提供了一个XPage运行时的上下文信息。
getCurrentDocument()和getCurrentDominoDocument()方法分别返回当前Document和DominoDocument对象。
getDatabase()的三个重载方法分别依据参数返回当前数据库对象。
getRequestMap()方法返回代表RequestScope变量的java.util.Map对象。
getRoles()返回当前用户的所有角色。
getSession()和SessionAsSigner()分别返回当前Session和以程序签名者身份的Session对象。
getUserNamesList()模仿@UserNamesList函数,返回的Vector<String>包含当前用户的所有用户名、具有的角色和所属的群组。
hasRole()和hasRoles()分别判断当前用户是否具有给定的一个或者多个角色中任何一个。
程序中用到的AppException就是笔者以前提到的一个简单的Exception的扩展,用以创建自定义的异常。
package starrow; public class AppException extends Exception { private static final long serialVersionUID = -143353750902427769L; public AppException(String message){ super(message); } }
com.acme.tools.JSFUtil来自以前的文章中也提到的KarstenLehmann的blog:http://www.mindoo.de/web/blog.nsf/dx/18.07.2009191738KLENAL.htm?opendocument