Source Code Enancements – Part 5 of the Series on the New Enhancement Framework
In this weblog I want to address several topics that center more or less around creating source code enhancements. At the beginning, I focus on the different use cases in which developers outside of SAP create an enhancement option. In a next step I narrow the scope and ask the question which type of enhancement option you should prefer as an option provider and in which cases a source code enhancement should be your first choice. As I have already stated in another weblog, in general SAP recommends the use of BAdIs. Still the BAdI is no all-purpose weapon. There are situations in which it is better to use source-code enhancements instead. After sketching these situations I will show you how to create an enhancement point, how to implement an enhancement point and how to overwrite an implementation created in another system without modifications.
Why to Define an Enhancement Option as a Developer Outside of SAP - the Different Use-Cases
Let us start by spending some thoughts as to when and why you might want to define an enhancement option as a non-SAP developer. Of course, it should be clear at the outset that in most cases you will implement enhancement options if you are a non-SAP developer. But as you will learn soon, there is one group of non-SAP developers that will take great advantage of defining enhancement options themselves. These are the ones developing solutions that should be enhanced by somebody else later. I will treat this group in the first use case. In contrast, the second use case is not confined to a particular group, but to any developer who is interested in keeping an unavoidable modification as small as possible.
1a.Imagine, you are an ISV, develop your product in ABAP and want to enable your customers to enhance your product at certain points. In this case, you provide enhancement options where you think they are useful.
1b. The same applies to the IT department of a multinational company. It develops some solution in ABAP and wants to make room for changes or enhancements that the different local subsidiaries can implement. Again using enhancement options are the suitable way to do this. Both cases are semantically and technically pretty the same, so that I decided to subsume them under the same use case.
2. The second use case is a bit more complex to describe: You are a SAP customer and need some enhancement of a SAP solution. Let us assume that the implicit enhancement options available in the relevant development objects do not suffice to accomplish this and that there are also no suitable explicit enhancement options. So you are left with the possibility to modify the relevant SAP development objects. But still there is room for using enhancement options. To reduce the effort necessary for adapting your modifications after an upgrade it is a good strategy to keep your modifications small. To minimize the size of your modification you create enhancement options within the modifications you insert. Then you add all further code to the implementation of these enhancement options. This way the modifications only contain these enhancement options and all the other additions are part of your namespace. In this use case modifications and enhancement cooperate in an interesting way.
The Limits of the Enhancement Framework
The very existence of this use case also helps to provide an answer to a question frequently asked: Namely, whether the new enhancement framework suffices to avoid all modifications. A realistic answer is: A clever use of enhancements enables you to do without modifications in many cases. On the one hand, there are explicit enhancement options provided by the developers of the respective solution. On the other hand, there are a huge number of implicit enhancement options. There are implicit enhancement points at the end of a function module, of a structure definition, of a report and of an include, in each defining section of a local class, and at the end of the implementation of a local class. Moreover, you can enhance a function module by additional parameter. A global class also offers a variety of implicit enhancement options: You can add methods, attributes, and interfaces to the class. Each method can be enhanced by a pre-exit, a post-exit and an overwrite-exit that substitutes the original implementation of the method.
Looking at the huge number of different implicit enhancement options it is probably possible to achieve your aim without modification very often. But still this is not always possible. Let us put it this way: What the new enhancement framework offers is intended to support modification-free enhancements to as large an extent as possible. But still, there is no guarantee that this is always possible. In case the enhancement options available for you do not suffice you should decide to create an enhancement option as a modification.
When to Use Source Code Enhancements
So much for the question when to create an enhancement option and the little excursus on the limits of the enhancement technology. The next question is what enhancement option you should prefer. In general, SAP recommends using a BAdI whenever it is possible. This is due to the reasons already named: A BAdI has a well defined interface and because of that the enhancement option provider has a firm control of the implementation. Moreover, the implementations can only access the data passed to them by the parameters of the respective methods. And again, it is you the BAdI provider, who determines which data should be passed to a BAdI method.
This great advantage of the BAdI is also a drawback in some situations. Thinking about this leads the way to understanding under which conditions a BAdI is not the suitable solution if you want to provide an enhancement option. This is, for example, a situation, in which you do not know which data the potential implementer of your enhancement options needs or provides. To put this point another way, if you do not know the interface, you cannot and, of course, should not use a BAdI. Given this condition, you should use the technology of enhancing the source code.
This enhancement technology comes in two flavors:
- At Enhancement points an implementer can add some lines of code which are executed at runtime when the line with the statement ENHANCEMENT POINT is reached. Then the control flows proceeds to the next line after the enhancement point. There can be none, one or many active source code plug-ins (as these enhancement implementation elements are called) assigned to an enhancement point. All these source code plug-ins are executed in addition to the code that is enhanced.
- An enhancement point cannot be part of another statement. This means a statement cannot be enhanced. And that fact sets a limit to the power of enhancement points. For example, there is no way to add a new condition to the where clause of a select statement by using an enhancement point. This is one prominent use case for an enhancement section. Imagine you have a select statement:
SELECT a b c FROM my_table INTO wa.
and want to leave it to the implementer to add a where-clause or select other fields from this table. So you mark the select-statement as an enhancement section, which looks like this:
ENHANCEMENT-SECTION SEC_SELECT SPOTS ES_MY_SPOT.
select * from sflight into table struc.
Don't worry here about the details of the syntax. At this stage, you should just note that the code marked as an enhancement section is substituted by a source code plug-in as soon as one is provided. Obviously it is required by the logic of enhancement sections that one enhancement section can have exactly one active implementation.
Let me just restate the main point about the use of source code enhancements: This enhancement technology is suitable if you want to provide an enhancement option and cannot or do not want to specify an interface.
Defining an Enhancement Point
Now that you know why and when to use source code enhancements you are probably eager to know just how you create an enhancement point and how you implement it. Before going into any details let me just remind you of the basic structure of the enhancement framework that applies to source code enhancements as well: When you define an enhancement point, this point has to be part of an enhancement spot. This means if you cannot use an existing enhancement spot you have to create one when creating an enhancement point. The same applies in an analogous way to source-code plug-ins: A source code plug-in is uniquely assigned to an (simple) enhancement implementation. But this structure should be pretty familiar to anybody who has read the weblog in which I show how to implement a BAdI. (Simple) enhancement implementations serve as container for enhancement implementation elements.
So enough with the background structure. Let us go into the details and create an enhancement point. We go to the source code that we want to enhance, open the respective unit in change mode, put the cursor on a line and choose the right mouse menu:
In the next dialogue window we enter the name of the enhancement point and the name of the spot plus the name of the relevant package as shown below.
As a result an enhancement point is inserted into the code before the line where the cursor was:
This is what an enhancement point looks like. An enhancement point has a name that is unique within the source code unit it belongs to and is uniquely assigned to an enhancement spot.
Implementing an Enhancement Point
Now we switch our role. For the sake of simplicity we provide here both the definition and the implementation of our enhancement point. Of course, you know by now that the provider of an enhancement option and the implementer are two different roles. To implement an existing enhancement point is not possible in the change mode for an obvious reason. Of course not. The one who implements an enhancement option does not want do modify the program. That is what the whole business of the enhancement framework is about. So we switch to the enhancement mode by selecting the relevant button:
There we are. We choose the right mouse menu on the line where the enhancement point is and select Create in the submenu:
We get to this dialog window:
As I have told you have first to provide a container for the source plug-in, that is an enhancement implementation. Let us call our enhancement implementation ei_my_implementation. Of course you should not forget the explanatory text. It is possible to create a composite enhancement implementation by using the Create icon. But it is not necessary, and so we do without this meta-container here. And there we are:
Before inserting some code just note that the source code plug-in itself is not named. It is by assigning an enhancement implementation to an enhancement point that a source code plug-in comes into being. We just enter the code: WRITE 'implementation'.
After the code for the source code plug-in is supplied we should activate it by selecting the respective button:
Source Code Enhancements - The Structure of the Entities
For those who do not feel totally familiar with the structure of the entities, we have created so far let me just sketch the structure of entities we are concerned with:
Our enhancement point uniquely belongs to the (simple) enhancement spot es_my_spot. This spot is assigned to the (simple) enhancement implementation ei_my_implementation. (Simple) enhancement spots containing points or sections and the relevant (simple) enhancement implementations are in an n to m relationship. That means: Points belonging to one spot can be implemented by source code plug-ins belonging to different (simple) enhancement implementations. And source code plug-ins belonging to one (simple) enhancement implementation can implement points belonging to different (simple) enhancement spot. (This does of course not mean that one source code plug-in can implement different points) It is the compilation unit that holds the respective (simple) enhancement spots and (simple) enhancement implementations together: Spots containing points in one report cannot contain points in other programming units. The same is true for the enhancement implementations in an analogous way. An enhancement implementation cannot be assigned to points that belong to different programming units.
Source code plug-ins are unnamed. You create a source code plug-in by assigning a (simple) enhancement implementation to an enhancement point. In turn, this means that a (simple) enhancement implementation can only be assigned once to an enhancement point. Otherwise the identity of a source-code plug-in would be blurred. So much for the details of the structure of the entities involved when creating and implementing an enhancement point. By the way, the structure of the entities and the whole process of defining and implementing is pretty the same for an enhancement section. There is one notable difference: When implementing an enhancement section you have to make sure that there is not more than one active source code plug-in.
Replacing Source Code Plug-Ins
Now let us consider in brief how to handle a use case that is a bit more complex. Suppose you are a customer and want to change a source code plug-in created by a SAP industry solution. The background is that this code is specific to the industry solution and does not fit your needs totally though your company belongs to the respective industry. Changing the source code plug-in in the SAP namespace would, of course, mean modifying it. And this is no attractive move and should be avoided as much as possible. There is a better solution for this problem than modifying the source code plug-in in the SAP namespace.
The Enhancement Framework provides a nice feature to handle this situation. It enables you to overwrite an existing source code plug-in by using or creating a (simple) enhancement implementation that is an object of yours. This means you can substitute a source code plug-in without modifying the plug-in or the code unit it is plugged in. And this is how it works:
Position the cursor on the enhancement you want to replace, choose the right mouse button and select: Enhancement Implementation->Replace.
In the next dialogue window we have to enter the name of a new (simple) enhancement implementation. For reasons already given, it has to be a new one and has to be different from the enhancement implementation to which the source code plug-in to be substituted belongs:
What we do now is pretty the same procedure as when we originally implemented our enhancement point. We enter some code and activate it by selecting the button Activate Enhancements. This is what our enhancement point looks like now:
By using the respective entries in the context menu you can also change and delete source code plug-ins. But you should keep in mind: You should not touch source code plug-ins created by SAP as this would mean to modify a SAP object, in this case, the respective (simple) enhancement implementation. If a source code plug-in created by SAP does not meet your requirements, you should replace it in the way just shown in the last use case. So you should change and delete only the source code plug-ins you have created yourself. Instead of deleting an source code plug-in created by SAP you should replace it by an empty source code plug-in. Again, this is the way to avoid a modification.
By now you should have learned a lot of different things about the source code enhancement technology. Let us first consider the definition part or the role of the enhancement option provider. You know the use cases for this enhancement technology: As an option provider source code enhancements are the means of choice if you do not know the interface of the enhancements to be made. You can also create an enhancement point as a modification and add the rest of the code you need to a source code plug-in assigned to this enhancement point. This helps keeping unavoidable modifications small. Apart from these use cases, the enhancement technology recommended by SAP, in general, is to define a BAdI.
As to the implementing part, you know:
how to implement an enhancement point,
how to change or delete an source code plug-in of your own,
how to replace an existing source code plug-in in the SAP namespace.