Tuesday, November 17, 2009

Referencing Bind Variables in Groovy

Thanks to Steve Muench for #143, 'Referencing UserData Map Values from View Object Bind Variables in Groovy' from Not Yet Documented ADF Sample Applications for help on figuring this one out.

I needed a ViewAccessor of my ViewObject to execute based upon a parameter calculated at run time. Generally, ViewAccessors, with required bind variables, are executed based upon an attribute in the main ViewObject, but in my case my ViewObject had no values for its attributes, because I was using it as a searchRegion (for the data binding of an af:query component) and although the I was setting the bind variable as the first step in my task-flow, the attribute on which I was trying to base the ViewAccessor's bind variable would always return null. So I created the following class that can be called via Groovy:

package com.mycompany.myproject.model.util;

import oracle.adf.model.bean.DCDataRow;

import oracle.jbo.ExprValueSupplier;
import oracle.jbo.JboReservedVarNames;
import oracle.jbo.Row;
import oracle.jbo.StructureDef;
import oracle.jbo.ViewObject;
import oracle.jbo.common.ViewCriteriaRowImpl;
import oracle.jbo.server.ViewRowImpl;

public class VOUtils {

public static Object bindValue(ViewObject vo, String bindName) {
return vo.getNamedWhereClauseParam(bindName);
}

/*
* Returns the value of the namedWhereClauseParam from the supplied VO.
* This was created so that bind variables values could be accessed via Groovy
*
* Groovy Example:
* com.synergetic.sis.model.util.VOUtils.bindValue(adf.object,"AgencyIdBind")
*
*/
public static Object bindValue(ExprValueSupplier valSupplier, String bindName) {
if (valSupplier instanceof Row) {
return bindValueFromRow((Row)valSupplier, bindName);
} else {
StructureDef sd =
(StructureDef)valSupplier.getExprVarVal(JboReservedVarNames.RESERVED_VAR_STRUCTURE_DEF);
if (sd instanceof ViewObject) {
return bindValue((ViewObject)sd, bindName);
} else if (sd instanceof Row) {
return bindValueFromRow((Row)sd, bindName);
} else {
System.out.println("Didn't handle case when valueSupplier was a " +
sd.getClass().getName());
}
}
return null;
}

public static Object bindValueFromRow(Row row, String bindName) {
ViewObject vo = null;
if (row instanceof DCDataRow) {
Object dp = ((DCDataRow)row).getDataProvider();
if (dp instanceof ViewCriteriaRowImpl) {
vo = ((ViewCriteriaRowImpl)dp).getViewCriteria().getViewObject();
}
} else {
vo = ((ViewRowImpl)row).getViewObject();
}
if (vo != null) {
return bindValue(vo, bindName);
}
return null;
}
}


This class can then be used to lookup the value of the ViewObject's bind variable using the following Groovy expression:
com.mycompany.myproject.model.util.VOUtils.bindValue(adf.object,"BindVariableName")

2 comments:

Daniel Diniz said...

So, I was looking for something which I could use to set a view's bind variable based on another view's bind variable, using groovy code.

That's what this class does?

BradW said...

Hey, I tweaked one of the static methods to work in 11.1.2.4. I had a similar need and this is what it took to work.

public static Object bindValueFromRow(Row row, String bindName) {
ViewObject vo = null;
if (row instanceof DCDataRow) {
Object dp = ((DCDataRow)row).getDataProvider();
if (dp instanceof ViewCriteriaRowImpl) {
vo = ((ViewCriteriaRowImpl)dp).getViewCriteria().getViewObject();
}
else if (dp instanceof ViewCriteriaItemValueImpl){
vo = ((ViewCriteriaItemValueImpl)dp).getViewCriteriaItem().getViewCriteria().getViewObject();
}
} else {
vo = ((ViewRowImpl)row).getViewObject();
}
if (vo != null) {
return bindValue(vo, bindName);
}
return null;
}