With the availability of a sneak preview version of SAP’s Web Application Server 2004s, one might wonder what kind of new gadgets will be available for us developers starting with this release. As Thomas Jung already pointed out in his blog, SAP has started to ship its latest incarnation of Web Dynpro in the ABAP realm with this new release. This is the first of a series of blogs that will delve into the depths of dynamic programming. It will focus on accessing, reading, deleting and changing objects that reside within a Web Dynpro component. Specifically, it will cover topics like changing the layout of a view and the structure of the context as well as the dynamic embedding of other components and the creation of popup windows at runtime.
Since any form of dynamic programming involves handling objects one would rarely come across during developing applications with the workbench, we first need to take a look at the purpose of these objects and how they relate to each other.
A Short Introduction to Dynamic Programming
Dynamic programming mostly accesses objects of a component at runtime. So for a start lets do a quick recap on how a component is structured. It basically consists of a number of different controllers and a ComponentInterface. The three most often used controllers are the ComponentController, ViewController and WindowController. There are also a few more types of controllers, such as the Interface-, Configuration-, Custom- and WindowController. To simplify things a bit, I will be using the terms “view” and “window” instead of ViewController and WindowController.
It is possible to access many of these objects at runtime and to change them as well as other referenced objects. As an example, a developer can change the layout of a view within method wdDoModifyView, since the view is the owner of the layout of a certain screen area. For this purpose, the interface of method wdDoModifyView provides a parameter called VIEW, which is a reference to an object of type IF_WD_VIEW representing the instance of a view at runtime.
I am often getting asked questions like Which objects can be modified at runtime? or Which interfaces are public?. Well, to give a short answer developers are free to use the following interfaces to their advantage:
From their names you might already guess what kind of objects they represent or what their purpose is. In addition to the all those different interfaces, there is also the possibility to call static methods on certain public classes. The celebrities are:
Don’t be scared. I will focus on each of these classes and interfaces in great detail in upcoming parts of this blog series, but I have got to mention them here so you know what lays ahead and to give you an overview. Once those other blogs will be online, I will update this one and turn the names into links. I hope, you understand that we would otherwise get sidetracked completely. So let’s move on to…
Any layout of any Web Dynpro application is comprised of one or more views that contain View Elements. On each view, they are arranged within a tree-like structure. The root of such a tree is a TransparentContainer called ROOTUIELEMENTCONTAINER. Whenever you create a view in the Workbench, this container will be created as well. ViewElements can roughly be separated into two different categories – those that can be placed on screen (e.g. a Button) and those that can only be used within other ViewElements, such as a Column within a Table. ViewElements from this first category are as well called UIElement. ViewElements from the second category do not have a special name, but can be of one of two very important specializations: Layout and LayoutData.
An important specialization of UIElements are UIElementContainers (or in short containers). Those are able to aggregate other UIElements and thus display them inside of a certain screen area. You might wonder how those UIElements are arranged within such the container. Will they be displayed in a single line next to each other, within multiple rows or even within a grid? As you might have already guessed, that’s what the Layout is used for. So every container also aggregates a Layout ViewElement. A FlowLayout i.e. arranges contained UIElements in a single row whereas a developer can set properties to influence i.e. if such a row should wrap to the next line at the right border of a window. By default, the RootUIElementContainer contains a FlowLayout, but this can be changed by a developer at any time.
Every UIElement contains a LayoutData. Its type has to fit to the kind of Layout the container aggregates. For a FlowLayoutData this would a FlowLayout. Did you recognize the naming convention? It is always “Layout” or “LayoutData” with the same prefix for the same kind of layout. A LayoutData describes how a UIElement will be arranged within the layout of a container, such as if it starts in a new line or what kind of padding is used.
Since a picture can tell more than a thousand words, I would like to provide you with a class diagram that describes the information presented above.
A quick question for those who are not yet dizzy from reading all those technical background information: Is it possible to display a container within another container and if yes, why is it possible? The answer is: Yes, because a UIElementContainer aggregates UIElements and the UIElementContainer is derived from it.
You might wonder if Web Dynpro ABAP differs from Web Dynpro Java in its UI element model. This is not the case. Although there are a few very rare platform dependent differences (e.g. there is no type available in ABAP to represent a mime object for a FileDownload/-Upload), especially the basics, which are covered in this blog, are exactly the same. Aside from the model, the implementation had to be adopted to the ABAP platform and thus names had to be shortened to fit 30 characters and since mixed case for identifiers is not supported, the resulting name of classes and interfaces uses underscore characters instead of camelcase syntax. So the names of the classes that represent the above mentioned ViewElements are as follows:
- ViewElement -> CL_WDR_VIEW_ELEMENT
- UIElement -> CL_WD_UI_ELEMENT
- UIElementContainer -> CL_WD_UI_ELEMENT_CONTAINER
- Layout -> CL_WD_LAYOUT
- LayoutData -> CL_WD_LAYOUT_DATA
Now let’s recap for a moment and look at the implications of the above mentioned class hierarchy before we take a closer look at how the model is implemented Web Dynpro ABAP, because understanding this part is crucial for mastering dynamic programming in regards to sucessfully modifying the layout of a view at runtime.
Obviously, those classes are expected to be abstract. This means that you will of course have to cast pointers often. On the other hand, since everything that can be placed on screen, is derived from one of those five classes, it also offers you the opportunity to work with generic typed pointers. If you are uncertain about the type of an UI element, use the least generic typed pointer. It will always work.
Four of the five classes mentioned above seem to follow a naming convention. They all start with CL_WD_ followed by the actual name of the ViewElement. You can apply this scheme to all other ViewElements as well. So, if you want to use a button, the class in question will be CL_WD_BUTTON. But why is CL_WDR_VIEW_ELEMENT an exception to this rule? The reason is that all classes derived from CL_WDR_VIEW_ELEMENT are generated and CL_WD_* is their namespace. Do you remember my earlier comment about Web Dynpro ABAP and Web Dynpro Java having the same UI model? Both platforms generate their objects from exactly the same centrally maintained model that was designed by using UML and Rational Rose as a tool. The class diagram shown above was copied from there.
That’s all so far concerning the very basics of ViewElements. There are more aspects to be covered, such as aggregations, events and context binding, but those will be explained in detail due course of the upcoming parts of this blog series.
The next part will deal with accessing ViewElements, creating/deleting them and setting properties. Of course, all this will be done at runtime. In contrast to all the necessary theory described in this blog, the next part will as well provide coding examples for each subtopic.