If you have workflow applications then it’s most likely that you wanna make certain parts of your xPage READonly for certain states (eg. such that an approver cannot change the details of the request he has to approve)
In old days we used access controlled sections. xPages gives us the possibility to add ACLs to panels, that servers (almost) the same purpose.
Why only almost? Cause all elements you put there to set data (buttons, links etc.) won’t be hidden even if you use currentDocument.isEditable().
Here’s my workaround:
on the Visible property of such a button etc.
instead of just:
currentDocument.isEditable()
use:
currentDocument.isEditable() && !YourClass.hasParentReadACL(getClientId(this.getId()))
now create a YourClass (we use our StandardUtil as it contains “standard” methods) and add this method:
public static boolean hasParentReadACL(String id) {
String[] components = id.split(“:”);
UIComponent parent = null;
String parentId = null;
int i = 2;
// the || is important as repeat controls within custom controls use the same id, so we have to
// get their parent as unique parent
while (null == parent || parent instanceof XspDataIterator) {
parentId = components[components.length – i++];
parent = JSFConnector.findComponent(parentId);
}
UIViewRoot root = FacesContext.getCurrentInstance().getViewRoot();
boolean hasACL = false;
while (root != parent) {
if (parent instanceof UIPanelEx) {
if (null != ((UIPanelEx) parent).getAcl()) {
hasACL = true;
break;
}
}
parent = parent.getParent();
}
return hasACL;
}
and voila all your additional buttons etc. are hidden if one of the parent panels has an ACL!
Of course you might change the code to really check for a READ ACL. We only use ACLs for READ so this check is at the moment superfluous.
ah.. a not so minor thing: we define the StandardUtil in a SSJS library to easy reference StandardUtil, in your case you may wanna use:
&& com.yourcompany.YourClass.hasParentReadACL()