Wednesday, 17 June 2015

state machines validation using Groove expressions

Very often there is a business requirement that defines some kind of a state machine. Each business entity has its own lifecycle, it can be created, published, modified, archived and so on. Transitions between states are usually one way. If a bank transfer is complete it cannot be rolled back to the prepared state. In other words, it means that validation depends on new and old value of the same attribute.

Recently I've worked on such requirement and the validation have been implemented as valueChangeListener on af:selectOneChoice. There is simplier solution and development must be done in model layer. Reasonable because valueChangeListener is assigned to one instance of the attribute usage in the project. And such attribute may be used in various pages. And there is no guarantee that developers there know about such validation.

Because new value depends on the previous, it fits to other patterns as well. Employees in a company can have their salary attribute to be updated. But who wants to have the new salary lower than current? :) Nobody I think.

Please open entity Employees, select Salary attribute and specify new script validation rule:



Print command is just to log the new value in the JDev console. Further, specify the error message and run the example page:





Which is the most important here - Groove allows to refer to new and old values by using newValue and oldValue keywords.

Wednesday, 6 May 2015

data controls refactor and MDS-00013 exception

There are a lot of questions about MDS-00013 after refactoring DataControl.dcx file - renaming or moving to other locations.

As a starting point I have got ViewController project with one page and custom Model project with sample POJO Data Control. A page is using specified DC by presenting collection as a read-only table.

My SamplePojoDataControlImpl.java class is defined in model package in Model project. After data control creation I've got DataControls.dcx file created in the same package in the same project. Just to make sure that it works fine I'm creating test page with drag'n'dropped read only table there. The project structure looks similar to the screenshot below:



The page works good, so lets change it. The best way to achieve it is to refactor it. I would like to move java class to model.java package and DCX file to model.dc package. Also i'd like to rename java file just to make it more complicated. I've used Refactor menu from the toolbar, so each important thing should be changed. OK, so run the test page one more time and...



an exception... I've digged the Internet for phrase:

oracle.mds.core.MetadataNotFoundException: MDS-00013: no metadata found for metadata object {0}

and the solution is not so obvious. The key to fix the issue is to understand the ADF descriptors. The files that are in the background, contain a lot of magic inside and nobody likes to mix with them too often.

Each project that has got data controls inside, has got such descriptors. DCs are defined in DCX file. Data control registers are pointed by adfm.xml descriptors. In my case after refactoring the project adfm.xml points correctly the register and DCX file points to renamed implementation class:



I'll revert the value of id attribute of AdapterDataControl node to avoid changes in other layers. But even so the result of running the page is the same - MDS-00013 exception is thrown.


So what else needs to be checked? There is CPX file which maches pages or task flow steps with their definitions (pageDefs). It also tells to the ADF framework which data controls are used in the projects and where are they located.


Please look carefully on the dataControlUsages node. There is one definition and a path attribute. From java point of view the path is correct. But the path is not a real path. It should point to the DC id in the registry. So proper value there is:

model.dc.SamplePojoDataControlImpl


Please run it one more time and... now it works as it should be!

Meanwhile please also check my other posts about validation and proxying web services for more details about usage of POJO data controls in your projects :)

Thursday, 16 April 2015

useful tricks for ADF and services integration

Nowadays it's though to imagine an application that doesn't consume web services. In my previous post I've described how to add declarative validation on Data Control level. WebService Data Control have been the best example in my opinion. Now I would like to make a step forward about how to combine ADF and web services.

I believe that you have already watched ADF Architecture channel about services integration in ADF. Accodring to the architecture that Frank has described, you'll have web service proxy and kind of java facade. It helps to avoid UI changes caused by WSDL definition changes and gives a mean to cache the values. I assume that all of this is done. Let us explore POJO DC a little bit more.

The start point of this post is creation of transfer object and data access object: Person entity and PojoDataControlImpl class.


The second file is POJO DataControl implementation file. Having all this, please create the Data Control and a test page. Drag and drop persons collection as ADF Form and run it.




Let us focus on the first field which is age. Go to Bindings section and explore it. Right click on the collection in Data Control section. Click on Edit Definition.



What has happend? Framework creates XML file that corresponds with PersonEntity java class. Do you recognize the central part of JDeveloper? It is very similar to BC4J configuration wizard. And it allows to change it and use it in the same manner as BC4J entities. Please do some changes and run the page again.



The changes are applied to view layer by the framework. Nothing more to add. Need to iInternationalize your application? You've got model bundle file. Need to create new page? Just drag and drop attribute or collection and all of the validation, labels, read-only settings are applied.

Hope it is helpful :)