Considerations for Creating an Application Class Implementation
Oracle recommends that:
Implementations of related terms be grouped in a single class in which different methods are responsible for deriving the term's value.
This practice facilitates maintaining a manageable number of application classes.
In situations in which the probability is high that multiple related terms are accessed during a single business event:
You have a single implementation return a rowset, record, or vector containing the data for as many of the terms as possible.
When defining the term, you specify which data element in the rowset, record, or vector is to be used for the term.
The data library calls the appropriate application class based on the class and package information registered with the implementation. The application class is instantiated automatically and the specified application class method is invoked. The application class constructor must be coded to accept an instance of the AccessMethod class.
For example:
class LeadOppMetrics method LeadOppMetrics(&_oAccessMethod As EOCF_CLF_DL:Runtime:AccessMethods: Access Method); method LeadCountbyBO(); private instance EOCF_CLF_DL:Runtime:AccessMethods:AccessMethod &ioAccess Method; end-class;
The AccessMethod object enables the application class to access values for all the implementation binds (input parameters) that are needed by the implementation and all the information about the term being resolved.
The following partial code shows how an application class can access any of its implementation binds.
method GetCaseID Local any &CaseID; &CaseID = &ioAccessMethod.getBindValueByName("CASE_ID"); Local EOCF_CLF_DL:Runtime:Results:ResultsScalar &oResultsScalar; &oResultsScalar = create EOCF_CLF_DL:Runtime:Results:ResultsScalar(&CaseID); &ioAccessMethod.Results = &oResultsScalar; end-method;
The application class does not need to know how the data is retrieved and passed by the data library engine. The data could have been passed by the calling application, defined as a constant in context definition, or defined as a term and resolved by the data library engine. The application class can retrieve the data either by position or by name.
/* BO_ID is the name of the implementation bind;the bind name specified here matches the one to be specified at the time of registering the implemenation in &nBOID = &ioAccessMethod.getBindValueByName("BO_ID"); Here the request is made to retieve the value for the first bind. */ &nBOID = &ioAccessMethod.getBindValueByPosition(1);
Another way that the calling application can pass additional information to implementations or policy actions is to have the calling application use the addUserVariable method to add the information to the context object. To access this information, the application class uses the getUserVariable method.
For example:
&AdditionalData = &oAccessMethod.AMContext.getUserVariable("ExtraInfo);
Note: The shape of the data received by an application class using any of the previous methods will be a PeopleCode Any object. Therefore, the application class is responsible for converting the object to the appropriate data type before the value is consumed. If the application class has a method to be invoked by the data library engine, then that method should not require any parameters.
The following code is an example of an application class that has several methods for resolving terms.
class OperatorInfo method Get_Person_Name(); method Get_Person_Salutation(); method Get_Person_Title(); method Get_Person_Gender(); method Get_Person_BirthDate(); method OperatorInfo(&_oAccessMethodParam As EOCF_CLF_DL:Runtime: AccessMethods: AccessMethod); private instance EOCF_CLF_DL:Runtime:AccessMethods:AccessMethod &ioAccessMethod; end-class;
If the data library engine invokes an application class method, that method is responsible for deriving the results and for inserting the results in the AccessMethod object. The data library engine transmits the results to the calling application. If an application class method is not specified in the implementation definition, the constructor is responsible for performing these tasks.
The data library provides several mechanisms through which the application class can return the output value to the data library:
The application class instantiates one of the following application classes with the output value that needs to be passed to the engine.
ResultsRecord Record &oResultsRecord = create EOCF_CLF_DL:Runtime: Results:ResultsRecord(RecordVariable);
ResultsRowset Rowset &oResultsRowset = create EOCF_CLF_DL:Runtime: Results:ResultsRowset(RowsetVariable);
ResultsScalar Scalar &oResultsScalar = create EOCF_CLF_DL:Runtime: Results:ResultsScalar(ScalarVariable);
ResultsVector Vector &oResultsVector = create EOCF_CLF_DL:Runtime: Results:ResultsVector(VectorVariable);
The type of class to be instantiated depends upon the type of data that needs to be returned.
The instantiated object is assigned to the member of AccessMethod object.
Note: Application class objects are not cached. When the data library engine invokes the application class because the data is not available in the cache, the application class is instantiated by invoking the constructor, then the method specified in the implementation. Therefore, the instance variables created in the constructor cannot be shared across multiple methods of the same class to resolve different terms.
The following example is a partial code listing of how a value can be passed to the data library:
method GetCaseID Local any &CaseID; &CaseID = &ioAccessMethod.getBindValueByName("CASE_ID"); /* use the appropriate sub class of Results class for assigning value */ Local EOCF_CLF_DL:Runtime:Results:ResultsScalar &oResultsScalar; &oResultsScalar = create EOCF_CLF_DL:Runtime:Results:ResultsScalar(&CaseID); &ioAccessMethod.Results = &oResultsScalar;end-method;
The following is an example of an application class implementation.
import EOCF_CLF_DL:Runtime:AccessMethods:*; import EOCF_CLF_DL:Runtime:Resolution:*; import EOCF_CLF_DL:Contexts:*; import EOCF_CLF_DL:Runtime:Results:*; class CaseRecordInformation method CaseRecordInformation(&_oAccessMethod As EOCF_CLF_DL:Runtime: Access Methods:AccessMethod); method GetResultRecord(); private instance EOCF_CLF_DL:Runtime:AccessMethods:AccessMethod &ioAccessMethod; end-class; method CaseRecordInformation /+ &_oAccessMethod as EOCF_CLF_DL:Runtime:AccessMethods:AccessMethod +/ &ioAccessMethod = &_oAccessMethod; end-method; method GetResultRecord Local Record &result; Local number &nResolved_value, &nCaseID; Local string &sBusUnit; /* Retrieving the implementation bind using the API */ &nCaseID = &ioAccessMethod.getBindValueByName("CASE_ID"); SQLExec("SELECT BUSINESS_UNIT FROM PS_RC_CASE WHERE CASE_ID = :1", &nCaseID, &s BusUnit); &result = CreateRecord(Record.RC_CASE); &result.CASE_ID.Value = &nCaseID; &result.BUSINESS_UNIT.Value = &sBusUnit; &result.SelectByKey(); /* Passing the values (in this case, it is a record) back to the data library engine - this record could be used to resolve multiple terms */ &ioAccessMethod.Results = (create EOCF_CLF_DL:Runtime:Results: ResultsRecord (&result)); end-method;