One of the quite powerful features of ADF is the built in support user customizations also known as personalizations. A user can apply changes to an ADF web page – rearranging some of the layout, configuring advanced components such as tables and generally fine tuning the look and feel to the user’s individual needs. If the application is so configured, these changes are retained during the session (for each next visit to the page) or even across sessions (for each next visit to the page, also after an intermediate log out, in an entirely new session).
The framework provides declarative support for registering and reapplying the personalizations made by the user. These are held in the MDS Repository, in an XML file that contains the deltas that the user is (indirectly) requesting to have applied on top of the base sources of the application.
The framework does not have built in out of the box support for resetting the page – returning it to its factory level, the state in which the developers created it. The customization document needs to be removed from the MDS repository when the user wants to undo the personalizations made. To accomplish this, we need to write a little code and hook that somehow into our application. Documentation on MDS manipulation is not available on a large scale, but I found some very useful resources that provide most of what I need. Especially the article listed under resources below by Andreas Koop was very useful.
Here is what the final result looks like:
In a simple Table Page that can easily be customized by the user, I have added a link to remove personalizations:
When the link is clicked, the user is notified (through a message that is not really very useful – so we take it out when we go to production) that a document is removed from the MDS repository:
When the user next refreshes the page, you will see the page as it was, without the personalizations. In this case that means for example that the columns Primary Email and CellPhone are shown again:
On my MDS File Repository, I can see the document for this particular page and page fragment being removed:
Implementation
The implementation is quite simple, using the work done by Andreas Koop and others that is.
I have defined a new class – MDSCoordinator – and created a managed bean from it:
In the page fragment – that is part of a bounded taskflow that loaded into a dynamic region binding in a JSPX page -I have defined the following action link:
Through the setPropertyListener I pass the name of the fragment – EmployeesTable.jsff – to the bean that will remove the personalizations for the fragment. Note: I am still wondering if the name of the fragment itself could be easily derived at run time. I do not suppose the UI Component tree would give me an indication.
The code in the class MDSCoordinator consists of several parts. The action listener itself:
and the methods for querying
and deleting:
Resources
The class MDSCoordinator.
IDMClub Wiki on accessing the MDS API: http://idmclub.wikidot.com/metadata-store
Andreas Koop – ADF: MDS power user layer and “How to control MDS customizations at runtime” – http://multikoop.blogspot.com/2012/01/adf-mds-power-user-layer-and-to-control.html
Hi Lucas,
Great blog, very helpful. You were saying: “I am still wondering if the name of the fragment itself could be easily derived at run time. I do not suppose the UI Component tree would give me an indication.”
You are right about the latter. I just found a way to get it:
ViewPortContextImpl viewPort = (ViewPortContextImpl)ControllerContext.getInstance().getCurrentViewPort();
String pageUri = viewPort.getPhysicalURI(viewPort.getViewId());
Still have to test it thoroughly, but it seems to do the trick! Found it through the JDev debugger, the viewPort caches the latest URI of the current view. I was afraid I had to go through reflection to get it, but there was actually a function to do it. Only drawback is the cast to the Impl.