Professional Documents
Culture Documents
21.12.2009
Table of Contents
1. Authors ................................................................................................................................... 3
1. Scope of the Document ...................................................................................................... 4
2. Introduction to BOPF ......................................................................................................... 4
2.1. Business Object Processing Framework...................................................................... 4
2.2. Implementation Considerations ................................................................................... 4
2.3. Business Object ........................................................................................................... 5
2.4. How to check the Business Object .............................................................................. 5
3. Creating a Simple BO ........................................................................................................ 5
3.1. BO Creation ................................................................................................................. 5
3.2. Maintaining BO Settings ............................................................................................. 6
3.3. Business Object Nodes ................................................................................................ 7
3.4. Creating and Generating the DDIC Elements ........................................................... 10
4. Adding a Sub Node to the BO .......................................................................................... 13
5. Query ................................................................................................................................ 15
5.1. Creation of a Query ................................................................................................... 15
6. Alternative Keys ............................................................................................................... 23
6.1. Creation of Alternative Keys ..................................................................................... 23
7. Validation ......................................................................................................................... 26
7.1. Creation of a Validation ............................................................................................ 26
7.2. Implementation of Validation .................................................................................... 30
8. Determination ................................................................................................................... 34
8.1. Creation of a Determination ...................................................................................... 34
8.2. Implementing a Determination .................................................................................. 38
9. Action ............................................................................................................................... 40
9.1. Creation of Action ..................................................................................................... 40
9.2. Implementing an Action ............................................................................................ 42
10. Associations .................................................................................................................. 43
10.1. Association to a Delegated node ............................................................................ 44
10.2. Creating Association to Dependent Object ............................................................ 44
11. Testing the Business Object .......................................................................................... 46
2
1. Authors
Role Name
Author Santosh Kumar Goud Laddipelly
Author Frank Mock
Reviewer DL Suite_V&C_Architecture Team
3
1. Scope of the Document
This document should be a general help for people who want to do first steps with BOPF in
the Business Suite. It will cover the main steps that are needed to define a BO in the BOPF
framework. The main aim of this document is that it should be useful to everyone who is
using the BOPF for first time ever.
2. Introduction to BOPF
2.1. Business Object Processing Framework
The Business Object Processing Framework (BOPF) is a framework used to implement
Enterprise Services Oriented Architecture (eSOA)-compliant business objects. It provides
integrated functionality for business object implementation and leads to a common
programming model by design. BOPF controls the application businesses logic as well as the
data retrieval of the buffer and persistency layer. The main design principles are a clear
separation of the business logic and the buffering of data as well as a clear structuring of the
business logic in small parts with a clear separation of changing and checking business logic.
This framework offers an incremental and modular approach to your business object’s
implementation. You can quickly set up an initial, running prototype of your business object
with its most basic services already enabled (such as create, retrieve, updated, delete, save and
query). BOPF supports advanced enhancement and configuration options at every level, such
as defining the specific business logic and performance optimization attributes that are unique
to your business object.
4
Offers you the possibility to implement your Business Object in an incremental and
modular way
Leads to a high reuse of your business methods
Provides you with a running prototype in a very short time frame
Engineering approach for business object implementation; many parts are configured,
not implemented
Providing a common transaction model
Central user interface to configure your business object, which provides:
o Seamless integration with the ABAP development workbench
o Same look and feel as that of the backend systems
o Forward navigation support and creation of assigned classes, data structures
and database tables
o Versioning of the business object model and configuration
You can use these checks at any point of time during the creation of the Business Object. It is
strongly recommended to run the extended check at least before the transport of the Business
Object. The extended check indicates, if the execution of the Check & Correct function is
necessary.
3. Creating a Simple BO
This chapter is about the creation of a new business object by the help of the BOBF
Configuration UI.
3.1. BO Creation
When you create a Business Object in a Business Suite have to create the BOPF BO model
manually via the BOPF Configuration UI tool.
5
1. Start the BOPF Configuration UI (transaction /BOBF/CONF_UI from your
development system)
2. Create a Business Object by clicking create icon or by pressing F5
3. Enter the Business Object’s name you want to create and press enter (leave the super
business object field empty). In our example it is named ZMY_CUSTOMER.
4. You will be entering into a BO level as shown in the figure below:
5. Give a small description about the BO e.g., “My first BOPF BO”
6. Maintain the BO prefix “ZMY”. The prefix is used when BOPF proposes names for
repository elements. This will be done later on. A Business Object must either have a
prefix or a namespace (or both) in order to clearly separate its BOPF and DDIC
entities from other Business Objects.
Here we only select the constant interface at the BO-level. The constant interface carries
constants for all the elements of the BO that are needed to access the BO (for e.g., constants
for node, keys, associations, etc.).
6
As buffer class and data access class we use the default implementations provided by BOPF
which are already maintained in the corresponding fields. Alternatively we could also
generate our own classes. If we would do so, we would propose the names for theses classes
as well.
Till now we have just named the constant interface. Now we have to generate the same by the
following menu path ExtrasGenerate Repository ObjectsGenerate Constant Interface.
As a result the interface is generated and activated.
7
Give a small description about the root node
You can also change the root node name depending on your convenience
We keep the flags Node Can Be Loaded Separately and Node Can Be Locked
Separately.
Now we propose the names for a couple of DDIC elements. For each node of the business
object BOPF needs these elements during the handling of the business object’s data and for
the persistency of this data. We propose the names by following the menu path Extras
Propose Repository Names:
Data Structure: DDIC structure which contains the persistent attributes (fields) of the
node
Transient Data Structure (Data Structure tr.): DDIC structure which contains the
transient attributes of the node. In contrast to the persistent attributes, transient
attributes are only stored in the working memory and not in the persistency (e.g.
database).
Combined Structure: DDIC structure which contains the technical key fields and the
Data Structure and the Transient Data Structure as include
Combined Table Type: internal table with Combined Structure as line type. The table
type is used by BOPF to hold the data in memory and during communication with a
consumer, e.g. UI
Database Table: The database table which contains the node data. In the tutorial we
use a simple 1:1 relationship between nodes and database tables, i.e. each node is
stored in its own database table. Alternative approaches are possible.
8
You can see the figure below which displaying all the names as selected.
9
Here you can also change the names of the data structures and database table based upon your
requirements before the generation of the DDIC Elements. For this tutorial we change the
proposed names in order to reflect the BO name in the structures. Thus change the names as
follows:
Combined Structure name to ZMY_S_CUST_ROOT
Combined Table Type name to ZMY_T_CUST_ROOT
Data Structure to ZMY_S_CUST_ROOT_D
Data Structure (tr.) to ZMY_S_CUST_ROOT_DT
Database Table to ZMY_D_CUST_ROOT
10
2. Create Data Structure transient ZMY_S_CUST_ROOT_DT
Create the Data Structure by double clicking the name
ZMY_S_CUST_ROOT_DT
Create the structure in the DDIC as shown in the following figure
3. Now we can generate the remaining data structures using the BOPF generation feature
by following the menu path Extras Generate Repository Objects Generate
Dictionary Elements by which a window pops up to confirm the elements to be
generated.
11
Generate the data types by selecting Combined Data Structure, Combined Table Type
and Database Table in the popup as shown in the figure.
Now you can check whether the structures are generated properly by double clicking
them and navigating into the DDIC.
Note: You have to regenerate your constant interface after creating every new elements in
order to add the new or changed elements.
Your Business Object can be already used. You can just test it by the help of the generic
BOPF Test UI application - click on the execute button or press F8.
12
You can see the hierarchical tree of the Business Object created by you. Here double click the
root node click on create button in the right panel. Now you can create and save the data.
After this step there will be a pop up asking for the name of the sub node. Here enter the name
and the data model as shown below and press the Final button.
13
The Guided Procedure also allows to maintain an attribute mapping, but this is not required in
the Business Suite as we do not have any proxy Business Object. We also don’t maintain a
persistence mapping since the database table we use will have the same fields as the node’s
data structure.
Now you can see the sub node attached to the BO in the node structure in the Business Object
Detail Browser and you can create the data structure ZMY_S_BANK_DETAILS_D for the
Bank Details node as shown in the following figure. Double click structure name in the node
maintenance screen or go to SE11 and create the structure.
14
Afterwards repeat the steps from chapter 4 to generate the Combined Data Structure, the Data
Table and the Database Table.
5. Query
5.1. Creation of a Query
A query allows you to perform searches on business object nodes. For each node one or
several queries might be created. They provide the initial point of access to business objects.
Each query has an associated parameter structure. The result of the query can be
1. a set of all the node instance IDs or
2. a set of node instances including IDs and data or
3. a set of records in an internal table
that match the query criteria. Here in our example we are creating a query which is used to
select customer root nodes with using the data structure of the root node as query parameter
structure and the Combined Data Table as result table (option 3 from the list above). You can
create a query by accessing the tree on your left hand side as shown in the diagram.
15
After selecting the Create Query command a pop up comes up where you have to enter the
name of the query and the description. Fill the fields as shown in the figure below.
16
In the query we define a Query Result Type, i.e. the query implementation has to fill an
internal table that is type with Result Table Type. After query execution, BOPF directly
returns the table to the caller of the query. The result table is not buffered in BOPF. In
contrast, a query that does not specify a Result Table Type only returns the node IDs. Using
these node IDs BOPF then triggers internally the retrieve method in order to read the node
data if that is requested by the caller. As result, the BOPF buffer is filled with all node
instances corresponding to the queried node IDs. Thus the Result Table Type in a Query
should be used if the result must not be buffered in BOPF and you want to achieve the best
performance and memory consumption.
Now we create the query implementation: After you maintained the fields as shown in the
figure above press the finalize button. In the query details screen double click on the name of
the query class. Process the pop-ups to create the class, redefine the query method in the
17
created class and copy the code snippet listed below into it. Afterwards save and activate the
class.
METHOD /bobf/if_frw_query~query.
DATA:
ls_key TYPE /bobf/s_frw_key,
lt_selection TYPE /bobf/t_frw_query_selparam,
ls_selection TYPE REF TO /bobf/s_frw_query_selparam,
ls_sorting TYPE /bobf/s_frw_query_sorting,
lv_index TYPE i,
lv_max_rows TYPE i,
lv_where TYPE string,
lt_where TYPE STANDARD TABLE OF string,
lv_order TYPE string,
lt_order TYPE STANDARD TABLE OF string,
lt_range_key TYPE RANGE OF /bobf/conf_key,
ls_range_key LIKE LINE OF lt_range_key,
ls_comp TYPE cl_abap_structdescr=>component,
lt_comp TYPE cl_abap_structdescr=>component_table,
ls_range_r TYPE REF TO data,
lo_range TYPE REF TO cl_abap_structdescr,
lt_range TYPE RANGE OF string, "#EC NEEDED
ls_range LIKE LINE OF lt_range,
lt_result_db TYPE STANDARD TABLE OF zmy_d_cust_root,
ls_result TYPE zmy_s_cust_root,
lt_result TYPE zmy_t_cust_root,
lx_root TYPE REF TO cx_root.
FIELD-SYMBOLS:
<ls_result_db> TYPE zmy_d_cust_root,
<ls_range> TYPE any,
<lt_range> LIKE lt_range.
CLEAR:
et_key,
et_data,
es_query_info.
18
lo_range = cl_abap_structdescr=>create( lt_comp ).
CREATE DATA ls_range_r TYPE HANDLE lo_range.
ASSIGN ls_range_r->* TO <ls_range>.
AT END OF attribute_name.
IF ls_selection-
>attribute_name = /bobf/if_conf_c=>sc_attribute_name_key.
ls_selection->attribute_name = 'DB_KEY'.
ENDIF.
CONCATENATE ls_selection->attribute_name 'IN' lv_where
INTO lv_where SEPARATED BY space.
APPEND lv_where TO lt_where.
ENDAT.
ENDLOOP.
ENDIF.
IF is_query_options-maximum_rows > 0.
lv_max_rows = is_query_options-maximum_rows.
IF is_query_options-paging_options-paging_active = abap_true AND
19
is_query_options-paging_options-start_row IS NOT INITIAL.
lv_max_rows = 0.
ENDIF.
ENDIF.
TRY.
SELECT * FROM zmy_d_cust_root
UP TO lv_max_rows ROWS
INTO CORRESPONDING FIELDS OF TABLE lt_result_db
WHERE (lt_where)
ORDER BY (lt_order). "#EC CI_DYNTAB "#EC CI_DYNWHERE
es_query_info-count = sy-dbcnt.
et_data = lt_result.
ENDMETHOD.
Note: You have to regenerate your constant interface after creating every new object so as to
maintain the constants for all the elements.
Now you can test the query function using the BOPF test tool. Once the test tool has opened,
press enter and select the query as shown in the figure below. Double click the query,
maintain selection criteria as you want and execute it by press continue.
20
If you execute the query, you will recognize, that the results are only displayed in a popup
(see next picture).
At the time of writing this document it is not possible to take over the result of a query with a
Result Table Type into the main window. Thus we will quickly create an additional query,
which does not use the Result Table Type just to allow you to use the test tool. In order to
create the query go back into the BOPF Configuration UI and create a query again for the root
node with the settings shown in the figure below:
21
Please be aware of the difference between this query and the one with Result Table Type: The
new query does not specify an implementation class and remember the difference in the
buffer handling of the result: the results of this query are always buffered until the end of the
transaction (in most use cases this is not desirable). The query is executed by the data access
class of that node (/BOBF/CL_DAC_TABLE). This class has a generic query implementation,
which can be used when
1. The search parameters map to the node’s attributes and
2. No Result Table Type is used
In the future the data access class may also support the Result Table Type, but at the time of
writing that document it is not supported.
Now you can test the BO again as described above and using the newly created query.
22
6. Alternative Keys
6.1. Creation of Alternative Keys
An Alternative Key is a defined set of attributes of a business object node that identifies a
single (unique key) or a set of (non unique key) node instance. Alternative Keys are used
typically to model semantic keys of BO node.
From a definition point of view an Alternative Key is quite similar to a query. One major
difference is that a query searches by definition on the database only, whereas an Alternative
Key can search first within the transactional buffer and might afterwards also search on the
database if necessary. If the before image is requested it is identical to a query. The second
distinction is that an Alternative Key can be a key for the corresponding node. That means for
each combination of field values of the Alternative Key leads to exactly one result and
therefore to one Node ID. That information can be used to optimize the search in the
transactional buffer because as the search can be stopped if all requested node instances are
found. The third difference is that a query is defined as such over fields that can be located
everywhere within the BO Model. In some cases the query fields are even not part of the
Model at all. However the fields of an Alternative Key are all defined as fields of one node.
To create an Alternative Key we can use the tree on the left side of the screen as shown in the
figure below.
Maintain the name of the Alternative Key and provide a small description for your
understanding. In our example the name of the Alternative Key is CUSTOMER_ID. In
addition you maintain the Data Type, the Data Table Type and the Secondary Key.
23
In general Alternative Keys can be defined in two different ways
1) If an Alternative Key comprise several fields, you have to maintain a DDIC structure
in the Data Type field. In this case, each field in the structure has to map to a field in
the node’s Combined Data Table.
2) If an Alternative Key comprises a single field only, you can maintain a Data Element
in the Data Type field. In this case, the Name of the Alternative Key has to map to a
field in the node’s Data Type. Following this tutorial you define the Alternative Key in
this way. The Data Type field contains the Data Element
/BOBF/DEMO_CUSTOMER_ID and the name of the Alternative Key
CUSTOMER_ID maps to the field CUSOMTER_ID in structure
ZMY_S_CUST_ROOT_D. But you could also maintain a structure with a single field
here.
In the Data Table Type field you maintain an internal table which uses the type maintain in
the Data Type field as line type. In order to follow the example you need to maintain table
ZMY_T_CUSTOMER_ID that uses the data element /BOBF/DEMO_CUSTOMER_ID as line
type.
You also maintain a Secondary Key in order to achieve a good performance when using the
alternative key. The secondary key you maintain here refers to the node’s Combined Table
Type (not to the Data Table Type of the Alternative Key). Thus you have to maintain the
secondary key in the node’s Combined Data Table. BOPF takes over the secondary key
maintenance for you when you use the feature to generate DDIC Elements. You will do that
now: After you maintained the Alternative Key as shown in the figure above, generate the
relevant DDIC elements by following the menu path ExtrasGenerate Repository
ObjectsGenerate DDIC Elements. Maintain the settings in the popup as shown in the
picture below and click the generation button.
24
If you now look into the definition of the Combined Data Table Type of the node in the DDIC
you will see that a secondary key with the name CUSTOMER_ID and the component
CUSTOMER_ID was created.
25
Note: You have to regenerate your constant interface after creating every new object so as to
maintain the constants for all the elements
Now you can test the Alternative Key using the test tool. When you open the test tool by
pressing F8 you can find also the Alternative Key CUSTOMER_ID created by you in the
Meta Data and Instance Tree:
Double click the Alternative Key CUSTOMER_ID by which a pop up is opened
Click on the Append Row button and give a customer Id which is already existing in
the database
Click on continue to see the effect
7. Validation
7.1. Creation of a Validation
A Validation is an element of a business object node that describes some internal checking
business logic on the business object. There are two types of Validations
1. Action Validation to check if an action is allowed
2. Consistency Validation to check the consistency of the Business Object
26
An Action Validation is assigned to object-specific actions (e.g. Release) and to the
framework actions Create, Update, Delete and Save. An Action Validation is carried out
when an action is called but before it is performed.
A Consistency Validation can be used to check the consistency of a business object. They can
be triggered after a modification (Create, Update, Delete) of a node or during the execution of
the framework action check.
To create a validation you can use the Business Object Detail Browser. During the creation of
a validation you also have to decide if you want to create a Consistency Validation or an
Action Validation. In our example you create a Consistency Validation which is used to check
the uniqueness of the Customer ID after entering it.
In order to create the validation highlight the root node. In the context menu execute
command CreateCreate ValidationConsistency Validation. In the appearing popup enter
the name of the Validation you wish to create - in our case it is
CHECK_ROOT_CONSISTENCY
class name ZCL_CUST_V_CHECK_ROOT_CONS in field Class
27
In the next step mark the request nodes for the validation as shown in the following figure.
Request Nodes are the trigger for the execution of a validation. This means if a node instance
of the configured request nodes is changed the execution of the validation is triggered.
NOTE: Only Consistency Validation does have Request Nodes. Action Validation does not
have request nodes as the execution of Action Validations is triggered by the execution of the
action.
28
In the next step mark the Node Category for which the validation is executed. Each node
instance belongs to only one node category. Such a category allows you to group model
elements, like validations determination, into different configurations. At runtime BOPF
decides based on the node category of an instance which configuration needs to be applied
and executes the corresponding elements. In most cases you may have only one node category
– the default one - which is maintained automatically by BOPF. In these cases you will not
get in touch with it. However in this step you have to assign the validation to the node
category. For the example select the node category Root.
29
The Validation Sequence on the next step can’t be maintained sine you don’t have another
validation created yet, which could be executed before or after the current validation. Thus
processed with “Finalize Guided Procedure”.
In the example of this tutorial you reuse the existing validation implementation
/BOBF/CL_LIB_V_ALT_KEY. The class checks the uniqueness of alternative keys.
Remember that you have maintained the alternative key CUSTOMER_ID on the Root node
earlier. This alternative key maps to the CUSTOMER_ID field you now want to check for
uniqueness. Thus you can reuse the class.
30
You can find the class in the BOPF Library Browser. The BOPF Library Browser can be
reached via the entry screen of the BOPF Configuration UI as shown in the following figure.
Within the Library Browser open branch /BOBF/LIB_LIBRARY and double click on the class
name /BOBF/CL_LIB_V_ALT_KEY. Afterwards more details in the class are available.
31
As you can see there are many classes within the BOPF Library Browser which are all
provided for reuse. Thus make yourself familiar with them as you need.
Now let’s reuse the class. Thus go back into your business object and open the validation
CHECK_ROOT_CONSISTENCY you have created above.
32
In order to create the validation implementation double click on the class name
ZCL_CUST_V_CHECK_ROOT_CONS which you have named earlier during the creation of
the validation. Proceed the popups to create the validation. Once the validation has been
created, you have to change the Super Class of you created validation class. Switch the Super
Class of ZCL_CUST_V_CHECK_ROOT_CONS to /BOBF/CL_LIB_V_ALT_KEY. During the
switch you are asked to keep the redefinitions. Don’t keep them, discard them.
33
After the switch you can redefine the methods
/BOBF/CL_LIB_V_ALT_KEY~CREATE_MSG_DUP_KEY: is used to create (error)
messages for duplicate keys
/BOBF/CL_LIB_V_ALT_KEY~FILTER_RELEVANT_ALT_KEYS: is used to remove
alternative keys which shall not be checked by this implementation. Class
/BOBF/CL_LIB_V_ALT_KEY can perform uniqueness checks for all alternative keys
which are maintained on the node for which the class is executed and which are
configured as unique. If you want to execute the check not for each of these alternative
keys you can remove those alternative keys which are not relevant in this method
implementation.
In the example you implement in this tutorial you don’t need to redefine any method. For
simplicity reasons you can reuse the messages provided by the library class. Additionally you
have only one alternative key configured in your BO that you want to check. Thus after
switching the Super Class active your class and go back into the BOPF Configuration UI of
your BO.
Note: You have to regenerate your constant interface after creating every new object so as to
maintain the constants for all the elements. You can use the extended check for any errors and
also check and correct if recommended.
Now you can test the Validation using the test tool. Open the test tool by pressing F8,
maintain the Customer ID and see whether you get messages.
8. Determination
8.1. Creation of a Determination
A Determination is an element of a business object node that describes internal changing
business logic on the business object. It can be used to trigger business logic based on the
internal changes (in contrast to an action). A determination is mostly used to compute data
that can be derived from the values of other attributes.
There are two types of determinations: persistent and transient determinations. The category
indicates whether a determination alters persistent or only transient data.
Within this tutorial you will create a transient determination which calculates the age of the
customer after he/she was loaded from the database or the birthdate was changed.
To create a determination you have to select the option Create Determination in the Business
Object Detail Browser.
34
In the appearing popup provide:
A name for the determination you wish to create followed by a small description about
the determination. In our example it is CALCULATE_AGE
Choose the determination category. In our case it is a transient determination, because
only transient fields or nodes are affected by the determination
Choose the change mode: Use Only Read Mode for determinations with category
“Transient” and “Exclusive Write Mode” for determinations with category
“Persistent”. Thus for this determination you use Only Read Mode.
Give the class name which has to be implemented to maintain your determination. In
our example it is ZCL_CUST_D_CALCULATE_AGE
35
Proceed to the next step in the guided procedure and maintain the Request Nodes: Request
Nodes are the triggers for the execution of a determination. This means if a node instance of
the configured Request Nodes gets changed/ loaded the execution of the determination is
triggered. You also have to select which operation on the configured Request Nodes exactly
should trigger the execution. Possible operations are Create, Update, Delete, Load or
Determine. For this tutorial make your selection as shown in the figure below.
Optionally you could also select Read Nodes. The BOPF loads the configured Read Nodes
before executing the determination. If the implementation of the determination takes
advantage of the mass-enabeld core services, it does not make sense to maintain them (see
BOPF performance guideline for more information)
36
On the next step of the guided procedure you need to maintain the BOPF events at which the
determination is triggered. The determination for calculating the age shall be trigger after
customer root node instances are loaded from the database into the BOPF buffer or after a
consumer has changed the birthdate of a customer. Thus the triggering events After Loading
and After Modify need to be selected.
37
Business Logic
Determination Times & Trigger Conditions
Determination Time
After Modfiy X X X
During Check&Determine X
After Validation X X X
Before Save:
Only for
Persistent Before Consistency Check X X X
Determinations Finalize X X X
Draw numbers X (X)2 (X)2
During Save: Before Writing Data X X X
After Commit X X X
After Failed Save Attempt X X X
1) Trigger Condition „Load“ is only available, if at least one of the request nodes is a „transient“ one.
2) There is usually no need to take numbers during update or delete.
On the next step of the guided procedure you could maintain sequence dependencies between
determinations. Since you don’t have another determination that screen is empty and you
don’t need to maintain anything. Thus click the finalize button to complete the guided
procedure.
For your example determination paste the following code into method EXECUTE.
METHOD /bobf/if_frw_determination~execute.
DATA:
38
lt_chg_fields TYPE /bobf/t_frw_name,
lr_root TYPE REF TO zmy_s_cust_root,
lt_root TYPE zmy_t_cust_root,
lv_age TYPE datum.
io_read->retrieve(
EXPORTING
iv_node = is_ctx-node_key
it_key = it_key
iv_fill_data = abap_true
IMPORTING
et_data = lt_root
).
io_modify->update(
EXPORTING
iv_node = is_ctx-node_key
iv_key = lr_root->key
is_data = lr_root
it_changed_fields = lt_chg_fields
).
ENDLOOP.
ENDMETHOD.
Method io_modify->update collects all updates internally without passing the changes
immediately to the BOPF buffer. The BOPF buffer is updated later, after the execute method
was finished. If you need an buffer update early you have to call io_modify->end_modify
which triggers the buffer update. However, BOPF automatically calls this method after the
execute method was finished.
The number of determinations you configure for a certain event can have a strong impact on
the performance of your BO. Especially the modifications that are done within a
determination have an impact on the performance. Thus, the more determinations you use
(and by that the more modifications) the slower may be the performance of your BO. Thus
from a performance perspective you may use only one determination for a triggering event.
Also explicit calls to method io_modify->end_modify within your determination
implementation may impact the performance of your BOs. On the other hand side the reuse
potential of a determination is higher, if the determination is very fine grained, e.g.
responsible for a single field update. Thus the recommendation for BOs with high
performance requirements is: For each relevant triggering event configure only one
determination. Avoid calling io_modify->end_modify explicitly if possible. Reuse is shifter
from the determination itself to classes which are called within the determination, i.e. within
the determination implementation delegate the responsibility to other classes which you
design for reuse. You can then reuse/call these classes within different determinations.
The example determination that you have implemented in this tutorial you use a fine grained
determination for simplicity reasons only. For a “real life” determination you may follow the
recommendations above.
39
Now you can test the Determination using the test tool. Open the test tool by pressing F8 and
set/change the birthdate of a customer. The field Age is automatically calculated.
9. Action
9.1. Creation of Action
An action is an element of a business object node that describes an operation performed on
that node. An action can be used to allow the external triggering of business logic (in contrast
to a determination). BOPF supports different actions cardinalities: static actions, single node
instance action or multiple node instance action. When you use single or multiple node
instance actions the consumer must specify the node instance keys on which the action is to
be performed. For static actions the node instances keys are not used.
The action execution can be influenced by action validations (see above). When a consumer
calls an action, BOPF checks whether action validations are configured for the called action.
If this is the case, these action validations are executed before the action implementation is
called. Within the action validation you can reduce the number of node instance keys that are
afterwards passed to the action implementation. In addition you can configure an action to get
executed only, if an corresponding action validation does not return a failed key. This
configuration is done in the action configuration screen. The example in this tutorial does not
use that option.
In the example here you will create an multiple instance action on the Bank Details nodes
which locks the given bank accounts.
To create a action we have to select the option Create Action from the Business Object Detail
Browser as shown in the figure below.
40
In the displayed popup provide the following information:
Give the name of the action you wish to create followed by a small description about
the action. In our example it is LOCK_BANK_ACCOUNT
Set the Action Cardinality to Multiple Node Instances.
Set the Change Mode to Exclusive Write Mode.
Maintain a class name which implements the action. In the example maintain
ZCL_CUST_A_LOCK_BANK_ACCOUNT.
Skip the next step of the guided procedure (you don’t need to maintain read or write nodes).
On the third step select the node category as shown in the figure below.
41
Afterwards finalize the guided procedure.
METHOD /bobf/if_frw_action~execute.
DATA:
lt_bank_details TYPE zmy_t_cust_bank_details,
lt_chg_fields TYPE /bobf/t_frw_name,
lr_bank_details TYPE REF TO zmy_s_cust_bank_details.
io_read->retrieve(
EXPORTING
iv_node = is_ctx-node_key
it_key = it_key
iv_fill_data = abap_true
IMPORTING
et_data = lt_bank_details
).
APPEND zif_cust_zmy_customer_c=>sc_node_attribute-bank_details-
lc_status TO lt_chg_fields.
LOOP AT lt_bank_details REFERENCE INTO lr_bank_details.
lr_bank_details->lc_status = '01'. " locked
io_modify->update(
EXPORTING
iv_node = is_ctx-node_key
iv_key = lr_bank_details->key
is_data = lr_bank_details
it_changed_fields = lt_chg_fields
).
ENDLOOP.
ENDMETHOD.
Now you can test the action using the test tool. Open the test tool by pressing F8. Select a
customer, navigate to the customer’s bank detail node and execute the action.
42
10. Associations
BO nodes are linked by associations. BOPF supports different association types. The most
important one is the Composition association by which the BO node hierarchy is defined.
When you create a child node BOPF automatically creates a composition association between
the parent and the child node. In addition it creates two further associations: one from the
child node to the parent node (TO_PARENT) and one up to root node (TO_ROOT). The
composite association by default gets the name of the created node. Besides composition
associations BOPF supports:
Foreign Key associations: The key of the target node instance is contained in an
attribute of the source node.
Reverse Foreign Key associations: The key of the source node is contained in an
attribute of the target node. A Reverse Foreign Key association determines the keys of
those target nodes which contain the source node key as foreign key. The BOPF
composition association belongs to this type.
Specialization associations: A Specialization is a “filtered composition”. It filters the
“composition” by some constant values (e.g. role code). At runtime the check is
performed against a field in the target node.
Reverse Specialization associations: Is a kind of filtered Foreign Key association.
The target node key is contained in a specialized source node. This association
determines the target node key contained in the specialized source node.
Cross-BO associations: The target node of a Cross-BO-Association is located on
another BO then the source node.
Composition to Delegated Node: The composition to the delegated node is a special
composition.
Each association has a cardinality. BOPF supports the following cardinalities [1:0..1], [1:1],
[1:0..n] and [1:1..n]. BOPF does not checked automatically whether a node meets the
cardinality constraints maintained in BOPF. The BO implementation has to implement this
43
check. However, for mandatory child nodes – cardinalities: [1:1] or [1:1..n] – you can reuse
the library validation /BOPF/CL_LIB_V_MANDATORY_NODES (out of the BOPF library).
In order to embed a Dependent Object into a Business Object you have to create a Delegated
Node in the Business Object. During runtime, BOPF replaces the Delegated Node with the
complete subset of the Dependent Object’s. At runtime, BOPF delegates the calls to the
Dependent Objects node to the Dependent Object.
In this tutorial you will embed the Text Collection Dependent Object into the Customer.
Within this section you will embed the Dependent Object /BOBF/TEXT_COLLECTION into
you Customer BO. Thus open your Customer BO in BOPF and select the root node in the
Business Object Detail Browser. From the context menu select the entry as shown in the
following figure.
44
This command will create a Delegated Node directly underneath the root node. In the details
screen for the Delegated Node maintain the following fields:
Node Name: Names of the Delegated Node. Use the name Note.
Node Prefix: The node prefix is used by BOPF at runtime in order to identify the
Dependent Object which is called by a consumer. Example: The Collection used here
could additionally be embedded underneath the Bank Details node. Let’s assume this
for a while. When you access the embedded Text Collection via the BOPF APIs you
need to tell BOPF which embedded Text Collection you want to access – the one
underneath the Root node or the one underneath the Bank Details node. You use the
Delegated Node to provide BOPF this information. Thus both embeddings of the Text
Collection need to have a Node Prefix, to be more precise a different Node Prefix.
Description: Maintain “Customer note”
Referenced Business Object: Select /BOBF/TEXT_COLLECTION
When you create the Delegated Node as described above BOPF automatically creates the
required association to the root node of the Dependent Object. This is possible since the Text
Collection Dependent Object supports a standard linkage to a hosting Business Object. The
standard linkage is supported for each Dependent Object that fulfills the following
requirement: The embedded Dependent Object must have an alternative key on its root node
that uses /BOBF/S_LIB_K_DELEGATION as DATA_TYPE and
/BOBF/T_LIB_K_DELEGATION as DATA_TABLE_TYPE. Furthermore this alternative
key must be set to "Not-unique" to enable one-to-many usages of it.
Further details about the delegation concept can be found here:
https://wiki.wdf.sap.corp/wiki/display/BOPF/BS+BOPF+FAQ+and+Features#BSBOPFFAQa
ndFeatures-Delegation
Note: Don’t forget to regenerate the BOPF constant interface every time when you add or
delete something in the BO.
Afterwards you can test the embedded Dependent Object in the Test Tool. For this purpose
open the Test Tool (F8) for the Customer and create a new customer or select an existing one.
Navigate to node Root Note and press the Create Button. This will create the root node of
45
the Text Collection (you don’t have to maintain anything here). Subsequently navigate to the
content node and maintain a text.
You can test the Business Object using the test tool by pressing F8 in the Business Object
Configuration UI by which a separate SAP GUI window is opened showing the test tool
(transaction /BOBF/TEST_UI). This method was used several time trough out the tutorial.
The other method is using a manually written report. The report accesses the Business Object
via the Service Manager and the Transaction Manager. They provide the APIs you need to
access a Business Object from any consumer to trigger queries, to retrieve data, to modify
data and to execute actions. By triggering these operations, the determinations created in the
design time will get executed.
The first report performs a query on the Customer Root node and retrieves the Bank Details
for each Root node in the result set.
* Data declaration
DATA:
lo_customer TYPE REF TO /bobf/if_tra_service_manager,
lt_root_key TYPE /bobf/t_frw_key,
lt_root TYPE zmy_t_cust_root,
lt_bank_detail TYPE zmy_t_cust_bank_details.
46
The next report creates a Customer Root Node.
* data declaration
DATA:
lo_transaction_mgr TYPE REF TO /bobf/if_tra_transaction_mgr,
lo_customer TYPE REF TO /bobf/if_tra_service_manager,
lt_root TYPE zmy_t_cust_root,
ls_root TYPE zmy_s_cust_root,
lr_root TYPE REF TO zmy_s_cust_root,
lt_mod TYPE /bobf/t_frw_modification,
ls_mod TYPE /bobf/s_frw_modification.
The last report calls the action LOCK_BANK_ACCOUNT on all Bank Detail nodes
belonging to queried root nodes.
* Data declaration
DATA:
lo_customer TYPE REF TO /bobf/if_tra_service_manager,
lt_root_key TYPE /bobf/t_frw_key,
lt_bank_detail_key TYPE /bobf/t_frw_key.
47
lo_customer->query(
EXPORTING
iv_query_key = zif_cust_zmy_customer_c=>sc_query-root-
select_by_elements
IMPORTING
et_key = lt_root_key
).
48