Friday, September 09, 2005

Tapestry render solution

The solution to my render rant a couple days back has been tedious, but not difficult. Started out with:

/**
* Simple interface declaring required properties for a protected component to (en/dis)abling a component render and its disable(d) state.
*
*/
public interface IProtectedComponent{

/**
* Flag for allowing component render.
*
* @return a Boolean value
*/
public boolean getAllowRender();

}


Then I wrapped all of the default Tapestry components we're using, for example:

/**
* A protected PropertySelection component only rendered if allowedRender is true.
*
*/
public abstract class ProtectedPropertySelection extends PropertySelection implements IProtectedComponent{

protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle){
if(getAllowRender() == true){
super.renderComponent(writer, cycle);
}
}


Did this for:
Any
Button
Checkbox
DatePicker
Insert
DirectLink
LinkSubmit
PageLink
PropertySelection
Submit
TextFiel
ValidField

Then, in the base class pageBeginRender, added the following:

for(Iterator componentIter = components.keySet().iterator(); componentIter.hasNext();){
String componentId = (String)componentIter.next();
IComponent component = getComponent(componentId);
IBinding elementId = component.getBinding(ELEMENT_IDENTIFIER);

if(IProtectedComponent.class.isAssignableFrom(component.getClass())){
IProtectedComponent protectedComponent = (IProtectedComponent)component;
if(elementId != null){
//resolve rights to component
//boolean updateOrExecute = canAccess(elementId, CRUDAction.UPDATE);
boolean updateOrExecute = true;
if(! updateOrExecute){
//boolean canRead = canAccess(elementId, CRUDAction.READ);
boolean canRead = false;
if(!canRead){
//do not render the component
component.setProperty(ELEMENT_ALLOW_RENDER, "false");
component.setProperty(ELEMENT_DISABLE, Boolean.TRUE);
}
else{
//Render the component, but make it disabled
component.setProperty(ELEMENT_ALLOW_RENDER, "true");
component.setProperty(ELEMENT_DISABLE, Boolean.TRUE);
}
}
else{
//Render the component normally
component.setProperty(ELEMENT_ALLOW_RENDER, Boolean.TRUE);
component.setProperty(ELEMENT_DISABLE, Boolean.FALSE);

}
}
}
}

So, I'm basically cycling through all of the components and changing state based upon id attribute and rights to the element. By the time renderComponent is called, the allowRender and disabled properties are set. Thus, this ensures the component is handled properly based upon user rights associated to the id.

No comments: