Warning
As per the OTN thread the following solution makes use of "internal" ADF libraries which Oracle gives no guarantee will not change in the future. The following code was tested under 11.1.1.2.0 and is assumed to also work in 11.1.1.3.0, yet you should check carefully that this code works in future versions, as we said, there's no guarantees it will performed as required. Also note Frank Nimphius has raised ER 10198616 to request a public API for the internal ADF libraries used in this solution.
Solution
Developers who are familiar with BTFs in JDev will know that they have an initializer and finalizer property which via EL can call which ever bean code we desire. The following code solution is simply the EL method end points which are called.
I won't bother to explain the code solution, it should be fairly self explanatory:
public class SomeClass {The code above makes use of the following custom task flow utility class:
public void initializer() {
Map taskFlowInputParameters = TaskFlowUtils.getCurrentTaskFlowInputParameters();
logBtfParameters(taskFlowInputParameters);
}
public void finalizer() {
Map taskFlowReturnParameters = TaskFlowUtils.getCurrentTaskFlowReturnParameters();
logBtfParameters(taskFlowReturnParameters);
}
public void logBtfParameters(Map btfParameters) {
HashMaptaskFlowParameterValues = new HashMap ();
FacesContext facesContext = FacesContext.getCurrentInstance();
Application application = facesContext.getApplication();
AdfFacesContext adfFacesContext = AdfFacesContext.getCurrentInstance();
MappageFlowScope = adfFacesContext.getPageFlowScope();
for (Object parameter : btfParameters.values()) {
NamedParameter namedParameter = (NamedParameter)parameter;
String parameterName = namedParameter.getName();
String parameterExpression = namedParameter.getValueExpression();
Object parameterValue;
String stringValue;
if (parameterExpression == null) {
parameterValue = pageFlowScope.get(parameterName);
} else {
parameterValue = application.evaluateExpressionGet(facesContext, parameterExpression, Object.class);
}
if (parameterValue != null) {
try {
stringValue = parameterValue.toString();
} catch (Exception e) {
stringValue = "";
}
} else {
stringValue = "";
}
taskFlowParameterValues.put(parameterName, stringValue);
}
// log the taskFlowParameterValues parameters somewhere
}
}
import java.util.Map;Caveat
import oracle.adf.controller.ControllerContext;
import oracle.adf.controller.TaskFlowContext;
import oracle.adf.controller.TaskFlowId;
import oracle.adf.controller.ViewPortContext;
import oracle.adf.controller.internal.metadata.MetadataService;
import oracle.adf.controller.internal.metadata.NamedParameter;
import oracle.adf.controller.internal.metadata.TaskFlowDefinition;
import oracle.adf.controller.internal.metadata.TaskFlowInputParameter;
/*
* Note this class makes of "internal" classes that Oracle preferred we didn't use (as there's no
* guarantee they wont change. However as of JDev 11.1.1.2.0 there is no other solution for
* retrieving task flow parameter names.
*
* See: http://forums.oracle.com/forums/thread.jspa?threadID=1556568&start=0&tstart=0
*
* Oracle has raised ER 10198616 to create a public API for the internal classes in this case.
*/
public class TaskFlowUtils {
public static TaskFlowId getTaskFlowId() {
ControllerContext controllerContext = ControllerContext.getInstance();
ViewPortContext currentViewPort = controllerContext.getCurrentViewPort();
TaskFlowContext taskFlowContext = currentViewPort.getTaskFlowContext();
TaskFlowId taskFlowId = taskFlowContext.getTaskFlowId();
return taskFlowId;
}
public static TaskFlowDefinition getTaskFlowDefinition(TaskFlowId taskFlowId) {
assert taskFlowId != null;
MetadataService metadataService = MetadataService.getInstance();
TaskFlowDefinition taskFlowDefinition = metadataService.getTaskFlowDefinition(taskFlowId);
return taskFlowDefinition;
}
public static MapgetCurrentTaskFlowInputParameters() {
return getInputParameters(getTaskFlowId());
}
public static MapgetInputParameters(TaskFlowId taskFlowId) {
assert taskFlowId != null;
TaskFlowDefinition taskFlowDefinition = getTaskFlowDefinition(taskFlowId);
MaptaskFlowInputParameters = taskFlowDefinition.getInputParameters();
return taskFlowInputParameters;
}
public static MapgetCurrentTaskFlowReturnParameters() {
return getReturnParameters(getTaskFlowId());
}
public static MapgetReturnParameters(TaskFlowId taskFlowId) {
assert taskFlowId != null;
TaskFlowDefinition taskFlowDefinition = getTaskFlowDefinition(taskFlowId);
MapnamedParameters = taskFlowDefinition.getReturnValues();
return namedParameters;
}
}
This code hasn't yet been extensively tested, and in general just shows the programmatic technique for others to understand. Internally we've already generalized this code further to suit our own use case. If you find any bugs or obvious errors with the technique, leave a comment describing the problem you found and any solutions please.
No comments:
Post a Comment