You are on page 1of 21

Implement a GenIL Component and Simple Objects How to Guide

This page is under construction! Status:


in process
However, this how to guide does not include a coding example. For this please refer to the corresponding sample
implementation. You can find the sample implementation with many comments in package CRM_GENIL_SAMPLE. The sample
component is represented by class CL_CRM_GENIL_SAMPLE_COMP.

Table of Contents
Introduction
Release Relevance
How to Use
How to Use at SAP
Definitions
Overview
Architecture
Basic parts
General services
GenIL customizing
Model service
Data container
Component development
Basics
Model definition - IF_GENIL_APPL_MODEL
Interaction Interface - IF_GENIL_APPL_INTLAY
Filter Relations
Additions
Simple object development
Basics
Model definition
A read-only object
A changeable object
Transactional parts
Additions
How to Use at Customer Site
Example
FAQ
Related Architecture
Responsible

Introduction
This page explains the basics on how to implement a GenIL component. If you have WEBCUIF 7.01 (EhP1) or later releases
installed, please check also the other how to guides regarding the GENIL_MODEL_EDITOR and the handler concept. Both
might ease your life implementing your component.

Release Relevance
This HowTo guide focuses on the functionality provided with WEBCUIF 7.0. It includes additions introduce with WEBCUIF 7.01 (EhP1). These are
marked accordingly.

How to Use

How to Use at SAP


Definitions
Business Object (BO): A set of entities with common characteristics and common behavior representing well-defined business semantics. The
set of entities is generally accepted in the business world (for example in an international standard or industry best practices). Examples are
"Sales Order" or "Purchase Order".
Business Object Node (BO Node): A semantically related set of attributes of a business object. Smallest unit of the object model with
exclusively unstructured attributes. Business object nodes provide core services. A business object comprises one or more business object
nodes. Each BO node has assigned a unique name. A BO node can be either a root object, an access object, or a dependent object.
Examples:
Business object "customer invoice" has business object nodes "Customer invoice header" and "Customer invoice item".
Business object "sales order" has business object nodes "Sales order header" and "Sales order item".
Business object "employee" has business object nodes "Address", "Bank details" and "Date of birth"
Business Object Node Instance: Instance of a business object that is uniquely identified by the name of the BO node and an identifier (ID).
Relation: A relationship between two BO nodes that is assigned a unique, cross-component name. The relation is assigned "a cardinality value"
for each BO node. The navigation direction is a characteristic of the relation.
Root object: A root object is a special element within a group of BO nodes that are linked to one another in a hierarchy structure via
aggregations. The root object is the only object within this structure that is assigned as a superior object to all other objects. Each root object is
also an access object.
Access Object: An access object is a special type of BO node, whose ID can be used to determine both the attributes of the access object itself
and those of its dependent objects.
Dependent Object: A dependent object is a special type of BO node, whose attributes cannot be determined solely from the ID of this object, but
instead, only or together with the ID of the superior access object.
Query-Object: A query object is a special type of object whose attributes are the parameters of a search request. The result of a search request
are one or more associated access objects at the uppermost level of the hierarchy or a query result object. Each search parameter could only
take a single value or pattern for direct match.
DQuery-Object: A dynamic query object is a special type of object whose attributes are the parameters of a search request. Additional to query
objects the parameter could have multiple values or ranges and can also be associated with logical operators like greater than, less than, or
between. The result of a search request are one or more associated access objects at the uppermost level of the hierarchy or a query result
object.
Query Result Object: A query result object aggregates a set of attributes of several objects far faster access. Because of this aggregation query
result object are read-only by definition. For further object navigation query result objects should be related to access or root objects.
Abstract Object: A modeling object to reduce model data. An abstract object can take the place of an business object node in the BO hierarchy.
There needs to be at least one real access or dependent object inheriting from the abstract one to take its place at runtime. Abstract objects got
introduced with WEBCUIF 7.01.
View Object: A view object represents named part of the object model. It serves for reading purposes only. If it is requested a hard coded set of
objects will be returned.
Object Model: Number of business objects and their relations.
Read View: Tree-type partial structure within an object model whose root must be an access object.
Access tree: Subset of a hierarchy of instances.
Access path: Access tree without branches.
Component: A component is an ABAP OO class which implements the component interface described in this document. It exposes a set of
business objects to the Generic IL, which form an congregational hierarchy. Each component must have at least one unique root object.
Data Container: The data container is a service of the Generic IL for transporting data of business objects nodes. All business object nodes in a
data container form a strict hierarchy based on the object model.
Data Container Object: A representation of a business object node in the data container.

Overview
Architecture

Figure 1: General architecture of the GenIL


The generic interaction layer consists of a core module, which aggregates an arbitrary number of components. There is a special component for
so called Simple Objects. This special component acts as a normal component towards the core module but hides most of the normal complexity
for a simple object implementation.
The communication between the core and the components, as well as between the simple object component and simple object handlers is
restricted to well-defined interfaces in a request responds format. These interfaces are implemented by abstract base classes, which are the blue
prints for the real implementations.
Components and simple object handlers are special adapters to certain business objects. They are intended to translate between the uniform
access interface defined by the generic interaction layer and the already existing API(s) of business objects.

Basic parts
The generic interaction layer consists of the following basic parts:
Core module: Provides the consumer interface of the generic interaction layer for uniform access to all offered business objects as
single point of entry. It translates and dispatches all requests for the components and collects the results afterwards.
Model service: Provides access to all meta data which describes the available business objects, their nodes, properties and relations.
The service is generally available and can be used by components as well as consumers of the generic interaction layer.
Data Container: The data container is a transport container for tree like data structures with an object oriented API. All business object
related data within the generic interaction layer is exchanged via data containers.
Simple Object Component: This is a special component to ease the implementation for a certain kind of business objects, so called
Simple Objects, see definition. It defines an additional set of customizing, a simple view on the data container, and a special
communication interface.

General services
GenIL customizing

Basic customizing
The basic customizing consists of two steps:
the definition of GenIL components and
the definition of GenIL component sets.
First we have to define components. The definition is done in maintenance view CRMV_GIL_COMP and consists of the component name, a short
description, and the name of the implementation class. The other parameters are for optional use and are of informational kind.
After the definition of components we can define a component set. An component set is an arbitrary set of components, which should be used
together by the generic interaction layer. One may want to use just all components, but will lead to an unnecessary high system load and is
usually not required. Also for testing purposes it is very helpful to define an own component set with a very limited set of components. The
component set definition is done in maintenance view CRMV_GIL_APPCOMP.
If a component set should also use the simple object component the component SO2 must be included in the definition.
It is also possible to use view cluster CRMVC_GIL_APPDEF to made all the definitions. The cluster arranges the single views in the correct
sequence and supports hierarchical dependencies.

Read View definition


A read view in the sense of the generic interaction layer describes a subtree of the object model. Therefore each read view is assigned to at least
one component set which defines the model space. This assignment is done in maintenance view CRMV_GIL_APPVIEW. A view can belong to
an arbitrary set of component sets, but one must be marked to be the model space defining one.
After the assignment is done the read view itself can be maintained. This is done in maintenance view CRMV_VIEWREG. Here a read view is
defined by a set of entries as shown in Figure 2.

Figure 2: Table of view definition.


Each entry starts with the read view name it belongs to. Than the new view object is described by a number, the name of the relation to its parent
object, its name, and the number of its parent. If this entry should temporarily not be part of the view it may be marked as inactive.
The entries shown in Figure 2 define an object tree as shown in Figure 3:

Figure 3: Read View in Tree presentation.

Model service
How to understand the model term
One of the most important things in the concept of the generic interaction layer is the model definition, because most of the services and functions
rely only on the common model. When we talk about a model we think of an arbitrary set of business objects nodes with a well-defined set of
properties and relation between them. All this meta data together we call the model.
Since we are in an ABAP environment we have already a lot of meta data stored in the ABAP dictionary. We make use of this data and add only
the missing parts to our own model description.
The only thing defined by the GenIL is the data the model must include a how it has to be structured. The model data itself is not part of the GenIL
and is only managed by it during runtime.
The idea is that each component has its own model, describing the offered business objects, BO nodes, the relation between them, and relations
to BO nodes of other components. When a component is loaded this model information is derived and added to the runtime model. So the runtime
model is defined through the models of the loaded components.

Since WEBCUIF 7.01 you can create and maintain new GenIL models interactively using the GenIL Model Editor. See GenIL
Model Editor for further information

Model elements

Objects
As already mentioned a model consists of business objects structured in business object nodes and relations between them. The business object
nodes are subdivided into 3 kinds:
root objects,
access objects, and
dependent objects.
Further the GenIL concept introduces the service objects:
query service, and
dquery service.
Finally the special object kinds:
query result objects,
abstract object, and
view objects.
Depending on the object kind several actions for an object are allowed or prohibited. For instance, transactional behavior is only supported on root
objects, direct read access only for root and access objects, and so on.
The model of a component will always start with a root object (in case of a read-only component an access object may also make sense). This
root object is then related to one or more, in general, dependent objects. If the related objects are directly accessible (full key) they might be
defined as access objects. Of course the objects of a component can also have associations to root or access objects of other components.
Beside the object kind some more object properties are part of the object definition. The following table describes these fields in detail:
Legend: M: Mandatory, O: Optional, NA: not applicable
Field Name

Description

Root
Obj

Access
Obj

Dependent
Obj

Abstract
Obj

Query
Obj

OBJECT_KIND

Specifies kind of object

M:
'A'

M: 'B'

M: 'C'

M: 'X'

M: 'D'

OBJECT_NAME

Object name. Name must be unambiguous within all models in a


component set

CREATE_STRUC

DDIC structure containing fields which are required when creating


an
instance of a Root Object.

NA

NA

NA

NA

KEY_STRUC

DDIC structure representing the key of the Business Object Node

NA

ATTR_STRUC

DDIC structure representing the data part of the Business Object


Node

ROOT_OBJECT

Name of the root object an object belongs to.

MAPPING_TYPE

obsolete

NA

NA

NA

NA

NA

ATTR_NUMBER

This value will be determined from the given attribute structure

NA

NA

NA

NA

NA

WS_ENABLED

If true, object enabled for the usage by the Web Service Tool

RESULT_OBJECT_NAME

Name of the result object. Can be either a Root Object, Access


Object or Search Result Object

NA

NA

NA

NA

DYN_MODIFY_CHECK

Indicator whether a dynamic check for changeability of this object


is supported.
Possible Values are
IF_GENIL_SUPPORTED~STATIC_SUPPORT = 'S' and
IF_GENIL_SUPPORTED~DYNAMIC_SUPPORT = 'D': For static
support the evaluation is cached for each entity; in case of
dynamic support the evaluation is done anew with each call of
CL_CRM_BOL_ENTITY->IS_CHANGE_ALLOWED. Introduced
with WEBCUIF 7.01.

NA

NA

DYN_DELETE_CHECK

Indicator whether a dynamic check for deleteability of this object is


supported.
Possible values see explanations under DYN_MODIFY_CHECK.
In case of dynamic support the evaluation is done anew with each
call of CL_CRM_BOL_ENTITY->IS_DELETE_ALLOWED
Introduced with WEBCUIF 7.01.

NA

NA

NO_ERRORS_ACCEPT

Indicator whether inconsistent object changes are acceptable or


not

NA

NA

NO_INSTANCE_SAVE

Save for single root instances not supported. Save all or nothing.

NA

NA

NA

NA

DIR_CREATE_REQ

Triggers BOL modify() implicitly when creating a non-root object

NA

NA

NA

NON_UNIQUE_PARENT

If set parent object will be synchronized with every read operation.


Parameter should be rarely used, since this might reslut in
performance issues

NA

NA

NA

NO_DIR_ROOT_DEL

Indicator that a root object is not directly deletable, but requires


the full TX cycle with SAVE and COMMIT

NA

NA

NA

NA

DYN_CREATE_DATA

Indicator whether a dynamic create ability check and dynamic


default values are supported for this object.
Possible values are
IF_GENIL_OBJ_MODEL->DYN_CREATE_CHECK_SUPPORTED
= 'C' and
IF_GENIL_OBJ_MODEL~DYN_ATTR_DEFAULTS_SUPPORTED
= 'D' (which includes a dynamic create ability check). An
evaluation is available via
CL_CRM_BOL_ENTITY->IS_CREATE_REL_ENTITY_ALLOWED
and GET_RELATED_ENTITY_TEMPLATE. Introduced with
WEBCUIF 7.01.

NA

NA

NA

SWITCH_ID

ID of switch in the Switch Framework which influences the


presence of the object

REACTION

This field is only evaluated if the object is attached to a switch of


the Switch Framework. It indicates whether the object should be
available in the model or not in switch position 'ON'. If SWITCH_ID
is given an field is initial the object is available per default if switch
is ON

SUPER_OBJECT

Name of super object. Enables object to inherit settings of super


object. Introduced with WEBCUIF 7.01.

NA

NA

OBJECT_NAME_APP

Field is not evaluated by BOL/GenIL framework. Can be used by


application to store application specific object name

HANDLER_CLASS

Field is not evaluated by BOL/GenIL framework. Can be used by


application to store application specific content e.g. class for
handling this object in the GenIL component.

OPT_LOCK_SUPPORT

Used by a GenIL component to indicate that optimistic locking is


supported for an object -> 'X'. Details see Optimistic lock

NA

NA

ASYNC_SAVE_SUPRT

Used by a GenIL component to indicate that assynchronous


save/update is supported for an object -> 'X'. Details see
Asynchronous Save

NA

NA

MA_ENABLED

Used by a GenIL component to indicate mass access is supported


for an object -> 'X'. Details see TODO

NA

NA

Methods
The declaration of object specific methods is only supported for Root Objects, Access Objects, Dependent Objects, and Abstract Objects.
Field Name

Description

Root Obj

Access Obj

Dependent Obj

Abstract Obj

METHOD_NAME

Name of the business object method

PARAM_STRUCT

DDIC parameter structure

RETURN_TYPE

Either the name of an object or the name of a DDIC type

Attributes
Attributes of an object are defined by the attribute structure given in the object definition. Here only additional properties can be defined. Please
note: If you do not fill the attributes table, it fill be filled automatically
with all attributes of the attribute structure later on. If you decide to fill the attributes table you have to fill it completely.
Field Name

Description

Root
Obj

Access
Obj

Dependent
Obj

Abstract
Obj

Query
Obj

Query
Result
Obj

Dynamic
Query
Obj

View
Obj

ATTRIBUTE_NAME

Name of attribute

NA

DEFAULT_PROP

Property like read only, hidden, etc.


(see fixed values) which should be use
per default for this attribute

NA

NA

NA

NA

PROP_IS_FINAL

Flag marks the attribute default property


as not being changeable. Can be used
for performance optimizations.
Introduced with WEBCUIF 7.01.

NA

NA

NA

NA

USE_CONV_EXIT

Indicator whether a conversion exit


function module should be called for
converting from/to external string
representation of the attribute value.
This is automatically derived from the
DDIC definition of the attribute

NA

NA

NA

NA

NA

NA

NA

NA

STRUCT_INDEX

This is computed from the DDIC


information of the attribute structure

NA

NA

NA

NA

NA

NA

NA

NA

SWITCH_ID

ID of switch in the Switch Framework


the attribute is assigned to

NA

REACTION

This field is only evaluated if the object


is assigned to a switch ID. It indicates
whether the attribute is available or
hidden in switch position 'ON'. If it is
initial the attribute is available by default

NA

DYN_TEXT_SUPP

Indicator whether dynamic


Key-Text-Relation support is available
for this attribute or not. If
initial/undefined this will be tried out at
runtime. Introduced with WEBCUIF
7.01.

NA

NA

NA

Relations
We also distinguish 3 kinds of relations:
associations,
aggregations, and
compositions.
The allowed kind of a relation depends also on the related objects. For instance, the relation between a root object and a dependent object is
expected to be an aggregation or composition, but the relation between to root objects can only be an association.
In addition to the relation kind also the cardinalities of the source and the target object are part of the definition. These are mainly used to
distinguish between 1:1 and 1:n relation.
All relations are treated as unidirectional with a well defined source object (parent) and target object (child). The object kinds in the following table
are for the parent object.
Field Name

Description

Root
Obj

Access
Obj

Dependent
Obj

Abstract
Obj

Query
Obj

Query
Result
Obj

Dynamic
Query Obj

View
Obj

RELATION_NAME

Relation name. Name must be


unambiguous within all models in a
component set

NA

NA

NA

OBJECT_A

Name of Source Object

NA

NA

NA

CARD_A

Cardinality of the Source Object


(often 1)

NA

NA

NA

RELATION_KIND

Aggregation, Composition or
Association

NA

NA (should
be
association)

NA

OBJECT_B

Name of Target Object

NA

NA

NA

CARD_B

Cardinality of the Assigned Object


(often 0..n)

NA

M
(should
be 1)

NA

NA

DO_NOT_BUFFER

Indicator that a relation is never to


be buffered. Each time the relation
is traversed it need to be read from
the GenIL component.

NA

NA

NA

NOT_WS_ENABLED

If true, Relation will be not available


for Web Services build with the
OST

NA

NA

NA

SWITCH_ID

ID of switch in the Switch


Framework

NA

NA

NA

REACTION

This field is only evaluated if the


object is attached to a switch of the
Switch Framework. It indicates
whether the relation is available or
hidden in switch position 'ON'. If
initial the relation will be available
per default if switch is 'ON'

NA

NA

NA

FILTER_CLASS

Class which acts as an filter to


further restrict data accessed by
this relation. Introduced with
WEBCUIF 7.01.

NA

NA

NA

NA

USE_TAB_IF

Indicates that for reading data the


ITAB based interface shall be used.
Introduced with WEBCUIF 7.02.

NA

NA

NA

NA

NA

Using the model service


The model service offers a uniform access to the model data. The model is represented by an instance of interface IF_GENIL_OBJ_MODEL,
which defines the model API. The model data itself is not accessible.
An reference to the a model instance can be obtained via the service class CL_CRM_GENIL_MODEL_SERVICE. This class has some static
methods, which are related to the model. In general we distinguish between the design-time model and the runtime model.
For the design-time model it is always possible to obtain an instance of the model interface for any GenIL component set. It is also possible to
reload a design-time model from the components to react on changes.
The runtime model is normally given by the current instance of the GenIL core and its used components, which cannot be changed but extended.
The runtime model data data might also partly or fully reside in the shared objects buffer.
Once an instance of the model interface was obtained various methods can be used to answer typical questions like:
What is the kind of an object?
Which attributes an object has?
To which other objects is an object related?
...

Data container
The data container is the universal transport media used in the generic interaction layer for transporting complex object structures. It provides not
only the ability of transporting data, it also provides an object orient API for accessing the data.
The data container it self is fully hidden and only its API is visible to the user. The API is in general structured into container objects and object
lists. Both appear in several specializations. Figure 4 shows the relationships between the different API interfaces.
In general the navigation through a data container starts from a root list object by selecting a specific list entry. From this object navigation is
possible via a relation, which results then in a new object list and so on.
The object list interfaces allow selecting entries or looping on the list. As a special feature the root list interface, each data container starts with,
allows also adding new container root objects.
All container object interfaces allow the access to the object attributes and additional data, like attribute properties. In addition to this simple object
functionality the container object allows navigation to dependent objects as well their creation. The very specific root object interface allows further
functions only defined for the container root.

Figure 4: Interface relationships in the data container API


Beside objects and their attributes the data container carries also messages and attribute properties.
Messages are handle in two different contexts. They may either be assigned to exactly one root object instance or not. In the first case the data
container manages message container objects of arbitrary type as long they implement the message access interface
IF_GENIL_MESSAGE_CONTAINER. For the latter case a global message container is provided that supports different types of messages. The
access to the message containers is fully integrated in the data container API.
Attribute properties are predefined modifiers, which can be assigned to object attributes. There are modifiers used in the read case like
changeable, read-only, hidden, mandatory, or technical. These properties describe somehow the changeability of an attribute. For the modify
case we have the modifiers modified and initial. This additional information is necessary to allow modifying objects by only sending delta
information. The programmed default attribute property is undefined. Different default properties might be given by the component model. There it
is also possible to declare a property to be final, which means it cannot change during runtime.
The content of the data container is always component and purpose specific. This means it contains only objects of the component it is given to
and the content varies in read and write case. Therefore it is important to separate the the terms container root object and root object!

Component development
In the following we explain step by step how to implement a component. Figure 5 shows the object model of the GenIL sample component. In the
following section we will always refer to this model.
However, this document does not include a sample coding. For this we refer to the corresponding sample implementation, which is part of the
WEBCUIF delivery. You can find the sample implementation with many comments in package CRM_GENIL_SAMPLE. The sample component is
represented by class CL_CRM_GENIL_SAMPLE_COMP.

Figure 5: Model of sample component


The sample model represents the majority of possible cases in a model. It includes a several query objects returning root (OrderQuery), access
(OrderItemQuery), and query result objects (OrderItemQuery2) and a dynamic query object AdvOrderQuery. The root object Order aggregates a
dependent object OrderPartner and an access object OrderItem. The OrderItem is a composition with the dependent object
OrderItemShippingData. The OrderPartner refers to an Account, which is a different root object. Finally Account aggregates an abstract object
AccountAddress, which has two actual representations AccountAddressDE and AccountAddressUS.

Basics

A component of the generic interaction layer is represented as a global ABAP class, which inherits from the abstract base class
CL_CRM_GENIL_ABSTR_COMPONENT. From its base class it inherits two interfaces, one for the model retrieval, and one for the interaction
with the GenIL core, see Figure 6.
The base class provides a default implementation for each of the interface methods (in most cases an empty implementation). This means only
the needed methods have to be implemented/redefined.

Figure 6: Component definition.


Actually there are two base classes in the meanwhile. In the first version CL_CRM_GENIL_ABSTR_COMPONENT the signature of several
methods reflects the assumption that the key of a root object will be a RAW16 GUID. In the following this assumption does not hold for all
implementations, so the more general base class CL_CRM_GENIL_ABSTR_COMPONENT2 got introduce allowing an arbitrary key also for root
objects.
Depending on the actual key of your business object you may choose the one or other base class. The sample implementation uses GUID keys
and inherits from CL_CRM_GENIL_ABSTR_COMPONENT.

Model definition - IF_GENIL_APPL_MODEL


As mentioned above each component defines its own model and provides it to outside. The model interface IF_GENIL_APPL_MODEL includes
the methods for accessing the component model by the model service. This is normally done only once when the component is loaded.
So far the model interface consists of four methods:
GET_OBJECT_PROPS: Returns a table of all provided objects including their properties.
GET_MODEL: Returns a table with all relations between the objects of the component it self and associations to objects of other
components.
GET_DQUERY_ATTR_OPTIONS: Returns a table with the supported select option for the dynamic query objects.
IS_DQUERY_HINT_SUPPORTED: Indicates Whether a hint is supported by a Dynamic query. This is only relevant in conjunction with
Enterprise Search.

Warning
Do not place initialization coding into these methods!
See Shared Memory

It is up to a component to decide how to keep the model information. It may be hard coded, but the recommended way is a system, control, or
customizing table. If no additional, component specific data is assigned with the model data the central model storage provided by the GenIL
Model Editor may be used.
Whatever is returned by the component is expected to be understood and handled by the component afterwards.
In our sample component the object properties table looks as in Table 1. The create structure name have to be given only for root objects. In
order to have a formal relation between queries and there result objects the result object type can be given.
The relations table for our [sample component model] would look like Table 2. As you can see the relation between the query object OrderQuery
and the root object Order is not modeled.
Object name

Object kind

Root
object

Key structure

Attribute structure

Create structure

Account

A (Root)

Account

CRMT_GENIL_OBJECT_GUID

GENILT_ACCOUNT_ATTR

GENILT_ACCOUNT_CREA

AccountAddress

X (Abstract)

Account

GENILT_ADDRESS_KEY

GENILT_ADDRESS_ATTR

AccountAddressDE

C
(Dependent)

Account

GENILT_ADDRESS_KEY

GENILT_ADDRESS_ATTR

AccountAddressUS

C
(Dependent)

Account

AccountQuery

D (Query)

Account

GENILT_ACCOUNT_ATTR

AdvOrderQuery

G (DQuery)

Account

CRMT_GENIL_ORDER_SEARCH

Order

A (Root)

Order

CRMT_GENIL_OBJECT_GUID

CRMT_GENIL_ORDER_ATTR

OrderItem

B (Access)

Order

CRMT_GENIL_OBJECT_GUID

CRMT_GENIL_ITEM_ATTR

OrderItemQuery

D (Query)

Order

CRMT_GENIL_ORDER_SEARCH

OrderItemQuery2

D (Query)

Order

CRMT_GENIL_ORDER_SEARCH

OrderItemSearchResult

E (QResult)

Order

CRMT_GENIL_OBJECT_GUID

CRMT_GENIL_ITEM_SEARCHRESULT

OrderItemShipmentData

C
(Dependent)

Order

CRMT_GENIL_SHIPMENT_KEY

CRMT_GENIL_SHIPMENT_ATTR

OrderPartner

C
(Dependent)

Order

CRMT_GENIL_PARTNER_KEY

CRMT_GENIL_PARTNER_ATTR

OrderQuery

D (Query)

Order

CRMT_GENIL_ORDER_CR

CRMT_GENIL_ORDER_SEARCH

Table 1: Object properties table for sample component.


Object A

Relation name

Object B

Cardinality A

Cardinality B

Relation kind

Account

AccountAddressRel

AccountAddress

C (1)

B (0..n)

C (Aggregation)

Order

OrderItemRel

OrderItem

C (1)

B (0..n)

C (Aggregation)

Order

OrderPartnerRel

OrderPartner

C (1)

B (0..n)

C (Aggregation)

OrderItem

OrderItemShipmentDataRel

OrderItemShipmentData

C (1)

C (1)

B (Composition)

OrderPartner

OrderAccountRel

Account

B (0..n)

C (1)

A (Association)

Table 2: Model table for sample component.

Interaction Interface - IF_GENIL_APPL_INTLAY


Method parameters
To make the implementation of a component a bit easier the methods of the interaction interfaces IF_GENIL_APPL_INTLAY and
IF_GENIL_APPL_ALTERNATIVE_DSIL use a standardized set import and export parameters. These parameters will be explained in the
following.

Object and method names


Some of the methods take object name (CRMT_EXT_OBJ_NAME) or method names (CRMT_OBJ_METHOD_NAME) as import parameters. All
these names have to match to the declared once in the object model of the component. Names within the GenIL are always handled
case-sensitive.

Name-value-pair table IT_PARAMETERS (CRMT_NAME_VALUE_PAIR_TAB)


We use name-value-pair tables (NVP tables) as a unique transport mechanism for arbitrary parameter sets. Each table line has a field NAME,
which holds the name of the parameter and a field VALUE, which holds the value of the parameter in its character representation. The names are
in upper case and the data is simply moved to the character format without any special conversion or formating.
In general correspond the NVP tables to parameter structures. Therefore each component inherits the generic service method
FILL_STRUCT_FROM_NVP_TAB, which convert a given NVP table to the corresponding structure.

Data container root object list IV_ROOT_LIST


The data container root object list is the entry point to the data container. Depending on the actual method it is filled, pre-filled, or empty.
If it is empty, like in method GET_QUERY_RESULT, the result should be filled in the list.
In case of method MODIFY_OBJECTS it is filled and needs to be traversed to extract the changed data.
In case of method GET_OBJECTS it is pre-filled. Here it acts like a form to be filled in. Travers the data container and checks whats actually

requested and fill in the data. This open concept allows further the pushing of additional data not directly requested.
It is possible to iterate on a root list to access included objects and to add new ones. From an objects it is possible to retrieve further object lists in
order to traverse the whole container.

It is important to distinguish between the container root object, as part of the container root list, and the object kind, defined as
root objects in the model. These are not necessarily the same!

Request object IS_REQUEST_OBJECT / IT_REQUEST_OBJECT


The request object (CRMT_REQUEST_OBJ) is a structure containing an object name, an attribute list, a relation list, flags, and relation filter
objects, which specifies a restriction of the data to be returned. Normally it is expected, that a returned object has set all its attributes and all its
relations to other objects. Since the retrieval of all this data may take some effort it is possible to restrict the result to certain attributes and
relations to save performance. Furthermore a consumer, such as the BOL may have its own buffer and is not always interested in all the data.
Such restrictions can be given for any set of objects, so also a table of request objects can appear.
Partially the request object data is integrated in the data container construction when it is pre-filled. The container object methods
CHECK_ATTRIBUTES_REQUESTED and CHECK_RELATIONS_REQUESTED operate on this data. However, the request object holds
additional information and is therefore passes in parallel.
The semantic of the request object entry is as follows:
No request object entry does exist for a container object: the object is only in the container for structural reasons.
A request object entry exists for a container object: attributes are requested, except NO_ATTR_REQUESTED is set to ABAP_TRUE.
This is already evaluated by container object method CHECK_ATTRIBUTES_REQUESTED. If attributes are requested the set may be
restricted by entries in REQUESTED_ATTR.
If a request object entry exists for a container object all modeled relations are requested, except NO_RELS_REQUESTED is set to
ABAP_TRUE. This is already evaluated by container object method CHECK_RELATIONS_REQUESTED. If relations are requested the
actual set may be restricted by entries in REQUESTED_REL. This information is already used for pre-filling the data container and need
not additionally checked.
There might be a request object entry only in order to transport relation filter objects. This is an WEBCUIF 7.01 feature. The filter entries
need to be examined by the component implementation.

List of changed objects ET_CHANGED_OBJECTS


This table (CRMT_GENIL_OBJ_INSTANCE_TAB) is a plain list of changed object instances. Since there might be inner dependencies between
objects of a component the change of an object may imply also the change of another object not part of the container. To track such changes
outside a component all changed objects must be reported back. Note that also deleted objects must be part of this list, since the deletion is also
a special kind of a change.
To ease to use of the changed objects list it adheres to a recursive semantic, which means the entry of an object in the list will be interpreted as
change of this object, all its relations, and aggregated or composed objects recursively. So in the easiest case you simply add the root object to
the list after any change.
An object instance is represented in the list by its name and its object ID. The object ID is an external identifier, which is calculated from the object
key. The method BUILD_OBJECT_ID of tool class CL_CRM_GENIL_CONTAINER_TOOLS returns the object ID for a given object key.

Object list CT_OBJECT_LIST


The object list is a table of object instances, represented by object name and object ID, combined with a success flag.
Only instances of root objects can appear in the list. In CL_CRM_GENIL_ABSTR_COMPONENT the type of the table is CRMT_OBJ_LINE_TAB
and the type of the ID is CRMT_GENIL_OBJECT_GUID, which forces a RAW16 GUID. In CL_CRM_GENIL_ABSTR_COMPONENT2 all effected
method inherited from CL_CRM_GENIL_ABSTR_COMPONENT have a final empty implementation. They get replace by the versions from
IF_GENIL_APPL_ALTERNATIVE_DSIL, were the table has type CRMT_GENIL_OBJ_INST_LINE_TAB. There the ID has the generic type
CRMT_GENIL_OBJECT_ID which is a XSTRING.
The table is always passes as changing parameter. The success flag is set to ABAP_FALSE on input and is expected to be set to ABAP_TRUE, if
the operation was successful. It is also possible to append additional line to the table in order to inform the consumer about additionally process
objects.

Read access to a component


In this section we focus on the read access to a component and how to implement the related methods. The comtent of this section will be
sufficient for building a read-only component. This such a component it is possible run queries if the component provides any query object, and it
is possible to read objects with there attributes and dependent objects for given keys.

Queries
We distinguish two kinds of query services:
The simple query, which allow to pass a set of query parameters which need to match either exactly or at least by some pattern.
The dynamic query, which allows to pass a dynamic set of parameters. It supports ranges and logical operators, like greater that or less
that, including and excluding options, and multiple options per search parameter.
All simple queries declared in the model have to be implemented in method GET_QUERY_RESULT. A query object defines a set of query or
search parameters by its attribute structure and returns a set of result objects, which are either root, access, or query result objects.

The signature of the GET_QUERY_RESULT method is defined as follows:

methods GET_QUERY_RESULT
importing
IV_QUERY_NAME
type
IT_PARAMETERS
type
IS_REQUEST_OBJECT type
IV_ROOT_LIST
type

CRMT_EXT_OBJ_NAME
CRMT_NAME_VALUE_PAIR_TAB
CRMT_REQUEST_OBJ
ref to IF_GENIL_CONT_ROOT_OBJECTLIST.

Since a component can define many query objects the first parameter IV_QUERY_NAME is the name of the query to be executed. The second
parameter IT_PARAMETERS is a table of name value pairs, which holds the parameters for the query. The third parameter IS_REQUEST_OBJ
is the request object structure. The fourth parameter IV_ROOT_LIST is a reference to an empty data container for the result list.
All dynamic queries in the model have to be implemented in method GET_DQUERY_RESULT. A dynamic query object defines a set of query or
parameters by its attribute structure. Additionally it defines for each parameter a set of supported options and operators. A query object defines a
set of query or search parameters by its attribute structure and returns a set of result objects, which are either root, access, or query result objects
.
The signature of the GET_QUERY_RESULT method is defined as follows:

methods GET_DYNAMIC_QUERY_RESULT
importing
IV_QUERY_NAME
type
IS_QUERY_PARAMETERS
type
IT_SELECTION_PARAMETERS type
IV_ROOT_LIST
type

CRMT_EXT_OBJ_NAME
GENILT_QUERY_PARAMETERS
GENILT_SELECTION_PARAMETER_TAB
ref to IF_GENIL_CONT_ROOT_OBJECTLIST .

Since a component can define many dynamic query objects the first parameter IV_QUERY_NAME is the name of the query to be executed. The
second parameter IS_QUERY_PARAMETERS is a structure which holds the values for the standard parameters. Standard parameters are:
MAX_HITS: Delimiter for the number of result objects to return. If it is 0, no limit is set.
MATCH_TYPE: No use.
DROP_SEL_PARAMS_ALLOWED:
SELECTION_HINTS:
The MAX_HITS parameter should be respected by each dynamic query for performance reasons. The other standard parameters or not always
relevant.
The third method parameter IT_SELECTION_PARAMETERS is a table with the query specific select options. Each line of the table holds to
following fields:
ATTR_NAME: Name of the selection parameter.
SIGN: Indicator whether the objects matching the given criteria should be included (I) in the result or excluded (E) from the result.
OPTION: Logical operator, like GT - greater than or LE - less equal. See fixed value of domain BAPIOPTION for reference.
LOW: Value to compare with, lower bound.
HIGH: Value to compare with, upper bound. This applies only for certain options.
The content of table IT_SELECTION_PARAMETERS is close to ABAP range tables in order to allow easy conversion to them.
The fourth method parameter IV_ROOT_LIST is a reference to an empty data container for the result list.
The basic implementation of both query methods looks pretty much the same and consists of the following steps:
1.
2.
3.
4.

Branch according the given query name.


Convert given search criteria to internal format.
Execute the actual search receiving a result list.
Fill the result into the data container.

For filling the data container you create for each direct result object an instance in the root list using method ADD_OBJECT and giving object
name and key. You receive an instance of the created container object and flag it as direct search result by calling method SET_QUERY_ROOT(
ABAP_TRUE ). Optional you can set the attributes of the object (mandatory for query result objects) and may add dependent objects.

Since the data container is a very open concept it is possible to return any additional data with the search result. However, it is
very dependent on the consumer if this is useful or not, so it should only be done if it is less or no additional effort. The minimal
requirement is to return the keys by creating instances on the container root list.
If you decide to return additional data you may pass the container to method GET_OBJECTS to do the job. The signatures do
match perfectly for this purpose.

Reading objects
The most central method in the interaction interface IF_GENIL_APPL_INTLAY is GET_OBJECTS. It can be used for any kind of read access to
the modeled objects of a component. The signature of the method is defined as follows:

methods GET_OBJECTS
importing
IT_REQUEST_OBJECT type CRMT_REQUEST_OBJ_TAB
IV_ROOT_LIST
type ref to IF_GENIL_CONT_ROOT_OBJECTLIST.

The first parameter IT_REQUEST_TAB is a table of request object entries. The second parameter IV_ROOT_LIST is a reference to a data
container. This data container is already pre-filled with objects and represents in this way also the set of objects to be read. According to this
technique it is necessary to traverse the whole container and to fill in the requested data.
The content of the pre-filled data container follows some fundamental rules:
The container root list contains always access objects (including root objects).
A container includes exactly one type of access object, but several instances may appear. Thus are in the root list.
It can include an arbitrary set of dependent object instances (dependent on the access object).
Dependent objects in 1:n relation may have only one representative/place holder.
Relation to other root or access objects appear as foreign relations. Here the term foreign is related to the actual data container.
According to the above rules other root or access objects must reside in another foreign data container.
According to this rules each request to a component is always split by access objects. Therefore the number of access
objects should be considered carefully to avoid a to high fragmentation of requests!

The basic algorithm for implementing the GET_OBJECTS method is shown in Figure 7. The Object handler lane represents a code block which
handles a certain object type. This could be a special instance or simply a method or function module.

Figure 7: GET_OBJECTS - Basic algorithm.

Figure 8: Recursive part of the algorithm for an object handler.

Processing the root list, shown there, is a bit simpler then the process on the related object lists, shown in Figure 8. The major difference is that
objects of the root list have always a valid, where as the other list might just contain a place holder. The place holder is required since relation
them self are not represented by a separate API instance, so a related container object is always necessary. For relations know read so far the
related object are unknown, so no key could be given which leads to the place holder. In case of a 1:1 relation the place holder can be used by
simply assigning a valid key to it. In 1:N relations the place holder might be used as the first object by assigning a key. All other object should be
created with the place holder as template via method COPY_SELF_WITH_STRUCTURE called on the place holder.
The algorithm repeats recursively for each relation level.

Write access
Creating objects
The creation of objects is separated into the creation of root object instances and instances of dependent objects. In this section we only focus on
the creation of root objects. The creation of dependent objects is explained in section 0.
Root object instances are created within method CREATE_OBJECTS( ). The signature is as follows:

methods: CREATE_OBJECTS
importing
IV_OBJECT_NAME type CRMT_EXT_OBJ_NAME
IV_NUMBER
type INT4
IT_PARAMETERS type CRMT_NAME_VALUE_PAIR_TAB
IV_ROOT_LIST
type ref to IF_GENIL_CONT_ROOT_OBJECTLIST.

The first parameter IV_OBJECT_NAME is the name or type of the root object to be created. This allows a component to implement more than one
aggregational hierarchy. The second parameter IV_NUMBER is the number of instances to be created. The third parameter IT_PARAMETERS is
a table of name value pairs with the given create parameters. With parameters can appear in this table is defined by the create structure given in
the object properties. The fourth parameter is the reference to the empty root list of the data container, were the new instances should be filled in.
As the result of this method the given number of root objects should be created. This means at least object keys (RAW16 GUID) are assigned and
the objects are further known to the component. It is also possible send the attributes for the created object if there are some default values.

Modifying objects
The modify method is probably the most complex method in the interface. It is used for any modification of attributes, and for creation and deletion
of non root objects. The signature is as follows:

methods: MODIFY_OBJECTS
importing
IV_ROOT_LIST
type ref to IF_GENIL_CONT_ROOT_OBJECTLIST
exporting
ET_CHANGED_OBJECTS type CRMT_GENIL_OBJ_INSTANCE_TAB.

The importing parameter IV_ROOT_LIST is the reference to the root object list of the data container. As in the read case the data container
follows some rules, but they are a bit different:
The data container starts always with instances of root objects of the component.
Access objects are treaded like dependent objects.
Each object carries a delta flag to signal its modification mode. The delta flag may state created, modified, or deleted. If it is empty the
object is unchanged and serves only for the structural integrity of the container.

There exists also an implicit export data, which is carried by the data container. We already mentioned that dependent objects are created during
the modify() method. After the creation their newly assigned object key must be set for the container object. That builds automatically a
key-mapping table.
Since the objects in the data container include only the changed attributes and not the full information the attribute properties can be used to
determine which attributes have changed.

Deleting objects
The deletion of objects is separated into the deletion of root object instances and instances of dependent objects. In this section we only focus on
the deletion of root objects. The deletion of dependent objects is explained in section 0.
Root object instances are deleted within method DELETE_OBJECTS( ). The signature is as follows:

methods: DELETE_OBJECTS
changing
CT_OBJECT_LIST type CRMT_GENIL_OBJ_INST_LINE_TAB.

The parameter CT_OBJECT_LIST is a table of object instances, represented by object name and object GUID, combined with a success flag.
The success flag must be set to ABAP_TRUE, if the operation was successful.
A root object instance, referenced in the list, is expected to be fully deleted (including aggregated dependent objects). The deletion on the
database must take place in update task. The commit work is given externally!

Transaction handling
Locking objects
Locking of objects is requested with the method LOCK_OBJECTS( ). The signature is as follows:

methods: LOCK_OBJECTS
changing
CT_OBJECT_LIST type CRMT_GENIL_OBJ_INST_LINE_TAB.

The parameter CT_OBJECT_LIST is a table of object instances, represented by object name and object GUID, combined with a success flag.
The success flag must be set to ABAP_TRUE, if the operation was successful.
Locking is always related to root object instances. If a lock for such an instance is requested the full aggregational hierarchy of the object is
expected to be locked.
Unlocking is then trigger by either the saving or initializing the object.

Saving objects
Saving of objects is triggered with the method SAVE_OBJECTS( ). The signature is as follows:

methods: SAVE_OBJECTS
changing
CT_OBJECT_LIST type CRMT_GENIL_OBJ_INST_LINE_TAB.

The parameter CT_OBJECT_LIST is a table of object instances, represented by object name and object GUID, combined with a success flag.
The success flag must be set to ABAP_TRUE, if the operation was successful.
Saving is always related to root object instances. If saving is requested for an instance the full aggregational hierarchy is expected to be saved.
Database updates have always to be done in update tasks. The commit work is given externally!

Commit and Rollback


The global ABAP commands COMMIT WORK and ROLLBACK WORK are called externally. Each component, which was called to save objects,
is called again after the global commands. Depending on the command either the ON_AFTER_COMMIT or the ON_AFTER_ROLLBACK method
of the component is called.
Within these methods the component can do some cleanup. It is also expected that the locks for the saved objects are released.

Initializing objects
Initialization of objects is requested with the method INIT_OBJECTS( ). The signature is as follows:

methods: INIT_OBJECTS
changing
CT_OBJECT_LIST type CRMT_GENIL_OBJ_INST_LINE_TAB.

The parameter CT_OBJECT_LIST is a table of object instances, represented by object name and object GUID, combined with a success flag.
The success flag must be set to ABAP_TRUE, if the operation was successful.

Filter Relations
A Relation Filter is an optional part of the relation and can be used to restrict the access to data by means of time/date or any other arbitrary filter
criteria. The following figure depticts classes/interface you have to consider when utilizing this feature

Add the name of the filter implementation class to the GenIL model in method IF_GENIL_APPL_MODEL~GET_MODEL() by using the field
FILTER_CLASS of the return table RT_RELATION_DET. Example: see class CL_CRM_GENIL_SAMPLE_COMP.
If you want to support time-period filters, derive your filter class from CL_GENIL_REL_FILTER_TIME_BASE. Provide the supported data/time
format in the constructor. Constants are defined in IF_GENIL_RELATION_FILTER_TIME. Example: see class
CL_CRM_GENIL_SAMPLE_FILTER
If you want to have some arbitrary filter attributes in addition, derive your filter class from CL_GENIL_REL_FILTER_TIME_BASE and provide a
filter structure (DDIC) containing the filter attributes.

The the GET_OBJECT method is executied when data is requested from the GenIL component at runtime. Get a reference to the filter object
from IT_REQUEST_OBJECTS for the requested relations and retrieve data according to the passed filter criteria.
For BOL related information about this topic refer to How_To_BOL_Relation_Filter

Additions
Execution of object methods
Web Service Tool (WST) Enabling
The Web Service Tool enables the customer to easily create web service on top of genIL components. It is not mandatory but recommended to
implement an additional interface and enable the component for being used by the WST. For further information about WST refer to:
Web Service Tool
Web Service Tool UIU Contribution Interfaces - How to Guide

Simple object development


Basics
A simple object in the generic interaction layer is represented by a global ABAP class, which inherits from the abstract base class
CL_CRM_GENIL_ABSTR_SO_HANDLER. From its base class it inherits the interface IF_GENIL_DO_HANDLER for the interaction with the
generic IL simple object component, see Figure 7.
The base class provides a default implementation for each of the interface methods (in most case an empty implementation). This means only the
needed methods must be implemented/redefined.

Figure 7: Simple object definition

Model definition
A read-only object
A changeable object
Transactional parts
Additions

How to Use at Customer Site


see How to Use at SAP

Example
FAQ
Question: You are using a custom transaction context to handle potential changes on different business objects together. You observe
that for some root objects involved the INIT_OBJECTS method is called from the GenIL framework after you have commited the
transaction. For other object INIT_OBJECTS is not called automatically and the corresponding memory may not released. Why?
Answer:
The object initialization INIT_OBJECTS is called for root objects which have not been touched in the course of the transaction. For the objects
which have been changed it is the responsibility of the GenIL component to do cleanup work in the ON_AFTER_COMMIT event handler of the
GenIL implementation. Since IF_GENIL_APPL_INTLAY~ON_AFTER_COMMIT gets no object list as input, the GenIL component implementation
needs to take care about the objects just saved in the course of the transaction. See internal message 3116886-2009.
Question: I am running a suite7i10 application and get an exception CX_SFW_SWITCH_EXISTENCE. Why?
Answer:
The sample GenIL component references a switch which has not been delivered in suite7i10. By accident the component however was part of the
SHMSET representing the GenIL components loaded into the shared memory for component reasons. In order to overcome the exception and at
the same time accelerate the application start, use the SAP implementation guide to remove the SAMPLE reference in the SHMSET GenIL
component set definition. See customer note 907109-2009.
Question: I'm using method CL_CRM_GENIL_CONTAINER_OBJECT->GET_CHILDREN to access the children of a GenIL container
object. When should I set its parameter IV_AS_COPY to ABAP_TRUE?
Answer:
Set the parameter IV_AS_COPY to ABAP_TRUE in case you do not have to know about new childs added during processing of the GenIL
container object list. In order to get the container list updated whenever a new child is added to the parent container object set the parameter to
ABAP_FALSE. This of course takes away some processing time.

Related Architecture
Generic Interaction Layer

Responsible
Responsible DEV: Uwe Reimitz, Martin Wegmann
Responsible IMS:
Responsible PM: n.a.

You might also like