Thursday, 21 July 2016

quick way how to implement parameterized popups in ADF

    The business case is very common - there must be a popup which should be parametrized. As usually, I don't want to code it and I want to get it fast. I've done it for several times earlier, and even during this demo I've forgotten about one of the attributes.

    My popup will show a region, in my demo I've created a simple task flow with one input parameter and one view activity.

    After that I've started to work on the test page. There I've created two buttons with <af:setPropertyListener> tags to assign parameter. You can use managed beans or other ways, in my case I'm creating implicit parameters in one of ADF memory scopes. I'm using request scope or view scope because they're living for the shortest amount of the application life time. 

    I'm creating a popup with a dialog and region inside. The popup itself must have contentDelivery attribute set to lazyUncached. The tricky part is with setPropertyListener and showPopupBehavior tags under the buttons. First one must have type attribute set to action, second the triggerType attribute to click.

    It's almost everything, the final last thing that needs to be changed is in the page definition file. Because the region relies on the input parameter, to ensure that it'll refresh itself, please change refresh parameter to ifNeeded. And that's it, you can run it and check the results :)

Tuesday, 19 July 2016

transaction level validations

    Business Components for Java introduces three levels of validation:
  • attribute level
  • entity level
  • transaction level 
It is important to understand when they should be used and how to implement them.

    The attribute level should be used if some business rule applies just to it, for instance last name can't contain numbers or the phone number is mandatory. It is run for the attribute that is marked dirty in each of the entities, with an assumption that there is no other condition in the Groove implemented.

    On the entity level usually you should check for entity cross-attributes rules. For example is a person is foreigner, the passport number is required. It is run for each entity marked as dirty in the transaction, you can exclude some entities by setting a condition in Groove or by setting attributes that should be changed in order to fire validation. Because it is not needed to check for passport number if the foreigner flag attribute hasn't changed its value.

    Transaction level is on the top of the list. It is run once for all of the entities in the collection, that are marked as dirty.

    The wizard to create one is not so straight forward. First you need to start entity level validator, change it to Method like it's usually done for entity validators. But after that you need to go to the second tab and change validation level radio button. If you check previous tab then, the signature of the validation method has been changed. 
    For the test purposes I'm not putting the error message, there is no such need. Please ignore the warning popup after clicking OK. The EntityImpl class is created. I've put few lines of logging there and I've run the application module tester.
    It is not a good practice, but if you want to run the validation on whole collection, you can of course do it. By calling ((JboValidationContext)ctxList.get(0)).getSource()) you'll get EntityImpl class. On it you can call getDBTransaction().getRootApplicationModule() to find the application module instance (the root one, as the method name suggests), and then findViewObject() there.

Monday, 4 July 2016

How to access POJO data control current row's properties (using getDataProvider() method)

    I have created a POJO based data control which is returning a List<String> iterator. Because of some reasons I need to work not only with the direct binds in the page definition but also I want to access current row's properties. To give a picture of the problem, I've prepared an example:

    And now I want to put on the same page af:selectOneChoice component with all of the Strings from the list in my POJO DC. The most important thing is that the current row is not an instance of java.lang.String. It is an instance of oracle.adf.model.bean.DCDataRow class. Quick look into the JavaDoc, but no direct hint there. It is a wrapper that extends ViewRowImpl class (you may recognize it from BC4J stack). There is one method that, unfortunately, is not described in the documentation. It is called getDataProvider(), in EL it should be reffered as any other getter method. So, my choice component should look like this:

    And, to prove a point, it works also for more complex types of the data. Another example is for some artificial POJO class with two properties. After calling getDataProvider() on the current row you can call another getter method from the POJO class. In my EL for example it is #{row.dataProvider.label} to get label property. Please follow next few screens to check the solution.