Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 91

Webdynpro JAVA Material & Questions

General :

What is a Web Dynpro Application?

A Web Dynpro application is an application that can be called from the user interface. As an independent program
unit it connects a URL that can be accessed by the user with a window in the Web Dynpro component.

What is a Web Dynpro Component?

The component is the central, reusable unit of the application project. You can create any number of views in a
component and arrange them in any number of windows.

What are Web Dynpro Controllers?

The controller is responsible for programm control, determining the data flow between the view and the model and
handling events.
Web Dynpro controllers come in two distinct varieties: those with a visual interface, and those without.

 Controllers that have a visual interface are referred to as "view controllers".


 Controllers that have no visual interface are referred to as "custom controllers".

- An interface controller makes its data available to a higher level component.

What is Singleton node and Non-Singleton node?

Check this links

https://www.sdn.sap.com/irj/scn/wiki?path=/display/WDJava/Singleton%252band%252bNon-Singleton%252bNodes

Difference between Singleton node and Non-singleton node,Supply Functions.

https://www.sdn.sap.com/irj/scn/wiki?path=/display/WDJava/Supply%252bFunction%252bin%252bWebdynpro\\

What is Cardinality Property?

When a node is created in the context of a Web Dynpro component, the cardinality of the node is specified.

The cardinality property is composed of pair of values that controls the maximum and minimum number of elements
may contain at run-time.

Four Possible values :

0....1 ,0....n,1....1,1....n

Q: How to solve java.lang.UnsupportedClassVersionError: Bad version number in .class file provoked by a calling a
WebDynpro app developed in NWDS EhP1 for CE 7.1?
A: Probably, the deployed class is Java 6 whereas WebAS is Java 5. Steps to solve the issue:

1. NWDS -> Preferences -> Java -> Compiler -> "Compiler compliance level" has to be 5.0
2. Rebuild and redeploy and call the app.
3. If error still occours, NWDS may not use Java 5 JDK/JRE.
a. Close NWDS.
b. Check if you have a Java folder jdk1.5.0_xx (jdk1.5.0_16 for example) and xx has to be >= 14. If
you don't have such JDK version, please go to the official site
http://java.sun.com/products/archive/and download and install the old version.
c. Way 1: Open <NWDS CE7.1.1 install dir>\eclipse\SapNetweaverDeveloperStudio.ini and make
sure that the parameter -vm points to a Java 5 installation. If not, change it accordingly.
Way 2: Rename all Java 6 folders (e.g. prefix "x") so NWDS can not find them any more. Restart
the NWDS. NWDS shall complain about missing JDK/JRE and, depending on your version, may
show the JDK/JRE-selection dialog like at very first startup after installation.
d. Start NWDS.
e. Rebuild and redeploy and call the app.
4. In case this does not work check the build configuration of the development track
a. Open Development Infrastructure perspective
b. Select development configuration that you are using for development
c. In "Component Properties" view, open "Technology Specific" section.
d. Check that the JDK for local build is configured to JDK1.5.0_xx (jre may not work here)
e. Rebuild and redeploy and call the app.

Use components in bigger Web Dynpro projects (componentization)

1. Goal

Once you start developing with Web Dynpro you'll get excited about its functionality. Additionally it supports you a lot
in quickly developing web-based user interfaces.

Normally you start with one component and start adding more and more views to it. At a certain point you'll have so
many views in a component that it starts getting difficult to add new functionality to your Web Dynpro application. At
this point you start thinking if the Web Dynpro Components could help here. But normally you suppress this idea.
Supported by the rule "Never touch a running system!" you go ahead until it really starts hurting you to maintain all
these views in one component (see picture below).
Picture 1: Web Dynpro Explorer showing one component with many views

Picture 2: Diagram View of the default window

This section wants to give you some hints on how to migrate from a "one-component-only" application to an
application that uses components. Componentization itself is not very easy to understand. So please don't
understand this step-by-step solution as the only way to do it or as a comprehensive description.
Nevertheless it should help you over the first hurdles.

Note:

The example shown here is based on a simple Web Dynpro project. This is suitable for little developments. If you are
working in a team you should use the NWDI and the component concept that consists of products, software
components and development components. Have a look at the following link for more details:

http://help.sap.com/saphelp_nw04/helpdata/de/01/9c4940d1ba6913e10000000a1550b0/frameset.htm[\]

Furthermore you should keep the following issues in mind when starting Web Dynpro development:

 Don´t do any business logic in view controllers. All business logic should be done in the model.
If you have UI logic try to implement it in custom or component controllers, if possible in a separate DC. From
there it can be reused.
 Use a middleware Web Dynpro DC for the communication with your backend systems. So the UI developer does
not have to know anything about connecting backend systems, you can unify error handling, logging and other
cross-cutting issues. Furthermore in the Java world it is a common way to separate responsibilities into several
development entities.
 Always realize your first Web Dynpro project together with an experienced Web Dynpro consultant. The
consultant can show you best practices and prevents you from failing into a trap.

2. Pre-Requisites

SAP NetWeaver: 7.0 (formerly 2004s).


User: Already familiar with Web Dynpro Views and the context-concept.

Project: A Web Dynpro project with multiple views. These views might have 1:n relationships in the context they
display (e.g. a table with a list of projects and below a table with a list of comments that are related to a project).

3. Step-by-Step Solution

If you want to switch to a component based architecture you'll have to solve these major issues:

1. Wisely bundle the views you have to components


2. Share the same context within multiple components
3. Bundle all you components again into one application
4. Be able to update one component depending on an event triggered by another component

3.1. Bundling Views To One Component

This is maybe the most important part of what you need to think about. At the beginning you should try bundle the
views depending on their relationship to the context they handle.

Let's assume you have an application like the one described in chapter 1. This means you have a list of projects that
you administrate. Each project has a list of details and can have multiple comments.
Therefore we initially should create the following components:

 CompPrjList (the component handling the project list and all related views to add/edit/delete a project)
 CompPrjDetails (the component handling the project's details and all related views to edit)
 CompComments (handling the project's comments and all related views to add/edit/delete a comment)

To create them you need to simply copy your initial component and paste it into your project. As we need to
create three additional components we do it exactly three times.

These are the steps you need to go through:

TBD

3.2 Share the same context within multiple components

To have only one instance of your data inside your component you should create a "data" component. This
component will be used in all other components whenever you need to read/write data of you application (e.g., project
names, comments, other project details).

To create it copy again your initial component and paste it as a new component with the name "CompData" into your
project.

TBD

3.2.1 Connecting the data component with the other components

To make each component aware of the data component you need to assign the data component as "Used Web
Dynpro Component" to all other components. These are the steps you need to follow:

TBD

In this use-case we need to apply this change for the following components:

 CompRoot
 CompPrjList
 CompPrjDetails
 CompComments

3.3 Create a "root" component

For a better separation of "functional" components and their bundling you should create a separate "root" component
that will bundle all your components into one application. Therefore you need to create the following component:

 CompRoot

To create it copy again your initial component and paste it as a new component into your project.

3.4 Update one component depending on an event triggered by another component

Now that you have tieded-up all your components we come to the most important point. We need to ensure that the
data is shared with all components. Additionally we need to take care that each component uses the same instance
of the data component.

If we deploy our application without taking care of this issue, we will wonder that each component doesn't seem to
know the other components current context.

3.4.1 Change the data components' lifecycle

To make all components aware of the same context we need to change the lifecycle of all components that are using
the data component to "manual" instead of "create on demand". Therefore just walk through the following steps:
Picture 1: select the data component usage

Picture 2: Set the lifecycle to "manual"

In this use-case we need apply this change for the following components:

 CompRoot
 CompPrjList
 CompPrjDetails
 CompComments

Please be aware that the data component is part of the "Used Web Dynpro Components" of these four components.
If this isn't the case please refer to section 3.2.1 that describes how you do it.

3.4.2 Initialize the usage of the data component

As we have set the data components' lifecycle to manual in all other components we firstly have to initialize it. We
need to do this in our root component as this is the first one that our application "knows".

To do that, simply call the root components' controller and jump to the wdDoInit method.
Here you need to add some code:

public void wdDoInit(){

//@@begin wdDoInit()

wdThis.wdGetCompDataComponentUsage().createComponent();

IWDComponentUsage dataCompUsage = wdThis.wdGetCompDataComponentUsage();

//@@end

}
Picture 1: Double click the components' name

Picture 2: Double click the components' controller


Picture 3: Open the component controllers' implementation tab and insert the code

The first code line creates an instance of the data component.

The second line assigns the the data components' reference to a variable. This variable can now be used to tell the
other components where they find the data component that they use.

3.4.3 Provide the data components' reference to all other components

To provide the data components' reference to the other components we firstly need to create a way to provide that
reference. We need to do that for the following components:

 CompPrjList
 CompPrjDetails
 CompComments

The easiest way to provide the reference is to create a dedicated method in all of the components' interface
controllers.

From each components' interface controller we need to forward the reference to the components controller. Once the
reference has reached the components' controller we use the "referencing" mode to provide the controller with the
instance for the data component. The picture below explains the principle how this is handled.
Picture 1: Principle of "referencing mode"

So what needs to be done? Let's go on step-by-step and use the component CompComments as example:

 We need to connect the interface controller with the component controller


 We create a method called "referenceDataComp" in the interface controller
 This method will forward the reference it'll get from the root component to the component controller of
CompComments
 We create a method called "referenceDataComp" in the component controller
 This method will be used to connect to the data component through the "referencing mode"

Picture 2: Open the component "CompComments" and click on "create a data link"
Picture 3: Connect the interface controller with the component controller (no additional context elements
necessary)

Picture 4: Double-click on the interface controller


Picture 5: Add a new method to the component interface controller

Picture 6: Add the methods' name


Picture 7: Select a "Java Native Type" by clicking on "Browse"

Picture 8: Select the type "IWDComponentUsage"


Picture 9: Click on "Finish"

Picture 10: The newly created method for the component interface controller
Picture 11: Add the code line in the newly created method "referenceDataComp"

Now you have properly setup the components' interface controller. Next you need to double-click to the component
controller and do exactly the same steps as shown from picture 5 to picture 10.

Picture 12: To the same for the component controller now (see picture 5 to picture 10)

At then end you should have a method in the components' controller as shown below
Picture 13: The newly created method referenceDataComp for the components' controller

Picture 14: Switch to the implementation tab, search for the newly created method and enter the code shown
above

We accomplished our tasks for the component CompComments. We need to follow the same steps for the
components CompPrjList and CompPrjDetails now. Simply follow the instructions from picture 2 to picture 14.

Once all component interfaces are available we can now open our root component again and provide the
CompData-reference to all other components. Beforehand we firstly have to "tell" our root component where to get
the other components' referenceCompData-methods. So we will:

 Open the root component again


 Provide the root component with the other components' referenceCompData method
 Provide the reference to the data component to the other components through their referenceCompData method
Picture 15: Open the root component, click on "properties" tab and click on "Add"

Picture 16: Select all components and their interfaces and click on "OK"
Picture 17: That's how it should look like after adding the components

Picture 18: Switch to the "Implementation" tab and add the code as shown in picture

The three additional code lines in the root components' component controller call the other components' interface
controller and provide them with the reference to the data component.

From this point on every component is using the same instance of the data component.

3.4.4 Get the initial data from the data component

Up to here we haven't requested any data from the data component. That's something we need to do now.
To be able to get the data from the data component we need to request it. Therefore we'll have to:

 Create a new method "getData" in the data components' interface controller


 Forward the request to the components' controller
 Request the data in the component controller
 Use the data component method "getData" in the root components component controller method "wdDoInit"

Picture 1: Double-click on the data components' interface controller

Picture 2: Add a new method by clicking on "New" in the "Methods" tab


Picture 3: Add a new "Method"

Picture 4: Create a new method called "getData"


Picture 5: Once created it should be visible as new method in the component interface controller of
CompData

Picture 6: Switch to the "Implementation" tab and add the request to fill the context (in this case the list of
projects)

At this point we have now created a new method that can be called by the root components' controller. Therefore we
just add it to our code in "wdDoInit" of the root components' controller.
*Picture 7: *

That's it. Now your application should be working properly. Of course you need to adapt to the application
that you have. But these are the basic things you need to do.

Context Node Sorting

view
Sorting a Context Node

This code snippet will sort a model or value node. Original code written by Armin Reichert and was taken from the
following thread on SDN.

I<Node> node = <the node to be sorted>;

node.sortElements

new Comparator()

public int compare(Object x, Object y)

/* passed values are of type I<Node>Element */

<AttributeType> ax = ((I<Node>Element) x).get<Attribute>();

<AttributeType> ay = ((I<Node>Element) y).get<Attribute>();

if (ax == null)

return ay == null ? 0 : 1;

}
return ax.compareTo(ay);

} } );

Value Nodes,Model Nodes,Recursive Nodes

Value Nodes:

A Value Node is the most basic form of node that can exist within a Webdynpro Context. It is one in which all the
necessary metadata to define the node attributes either is stored within the node itself or is obtained from a local Java
Dictionary object. Value node attributes can be added manually as required and do not necessarily have to represent
a predefined data structure.

However, if you know that a certain combination of fields will be used frequently across the different contexts in your
application, then rather than repeating the structure declaration for each value node in each context, it is more
efficient to create a dictionary structure. Then, when you create a value node, you can obtain the attributes directly
from the dictionary structure using structure binding. Under these conditions, the attributes of the value node become
fixed, and can only be taken from the dictionary structure.

A value Node that uses structure binding may not have any further child attributes added to it, but you may add
further child nodes (which in turn may use structure binding if desired).

When creating a new element for a value node's element collection, the node can create the element object using the
metadata stored within it. In a generalized form, the coding looks like this (where {cn} is any context node):

I{cn}Element newValueElement = wdContext.node{cn}.create{cn}Element();

Model Nodes:

A Model node is similar to a value node in respect to it's API however there are three important differences

1) A Context model node makes a model object look like any other context node i.e. it gives the model object an API
that is very similar to a value node.

2) A Model Node is not considered valid until it is bounded to a corresponding model object; therefore a model node
always inherits its metadata from the model object to which it is bound.

3) The element collection in a model node does not hold the actual runtime data instead it holds a collection of
references to the relevant model object instances.

When creating the elements of a model node's element collection you cannot use the exact syntax shown above for a
value node. Instead, the instance of a relevant model objects. A reference to this instance is then added to the model;
node's element collection.

The actual runtime data is stored in the model objects, not in the model node's element collection.

For Instance, a new element can be added to the model node BAPI_FLIGHT_GETLIST_INPUT as follows:

//create a new model object instance

Bapi_Flight_Getlist_Input_bapiInput = new Bapi_Flight_Getlist_Input_bapiInput();

//Using the model object instance, create a new model

//node element
IBapi_Flight_Getlist_InputElement newModelElement =
wdContext.nodeBapi_Flight_Getlist_Input.createBapi_Flight_Getlist_InputElement(bapiInput);

//Append the new element to the model node's element collection

wdContext.nodeBapi_Flight_Getlist_Input.addElement(bapiInput);
Notice that the create{mn}Element() method of a model node cannot create a new element object on it's own; it
needs to be passed a reference to an existing model object. The Model object is the actual repository for the runtime
data and the references to these model objects are maintained in the model node's element collection.

Recursive Nodes:

If you wish to represent a recursive data structure within the context, a recursive node is the correct node to use. The
simplest example of recursive data within a hierarchical structure is a file system. A dictionary can contain either files
or subdirectories. This definition is then repeated for each subdirectory level down the hierarchy.

Within the context, a recursive node is a special node that has only two properties: name and repeatedNode. As with
any context node, a recursive node must itself name, but the repeatedNode property is where the recursion is
defined. This property holds a reference to some parent node and indicates that, at runtime, the location of the
recursive node will be occupied by a node of the type indicated in the repeatedNode property.

You should think of a recursive node as a design time placeholder used to indicate a node will be created at this
location at runtime, and will be of the type named in the repeatedNode property.

The node name identified by repeatedNode must lie on the direct path back to the context root node.

When a recursive node is created at runtime it always created as a non-singleton node. This is a hard-coded feature
and cannot be changed.

The Following code will use the recursive context structure shown below, to create a representation of the simple
directory and file structure shown below.
à File SystemRoot

SubDirectory

SubDirectory

SubDirectory

FileAtLevel4

FileAtLevel3

FileAtlevel2

FileAtlevel1
Public void buildRecursiveNodes ()

//Get reference to statically defined FileSystemNode

IFileSystemNodeNode fsNode = wdContext.nodeFileSystemNode ();

//Perform 4 levels of recursion

For(int i = 0; I <= 4; i ++){


//Create an element in the current FileSystemNode

IFileSystemNodeElement fsNodeEl = fsNode.createFileSystemNodeElement();

//Set the file name based on the recursion level

fsNodeEl.setName("File at level " + i );

//Bind the element to the node collection

fsNode.bind(fsNodeEl);

//Change fsNode to refer to its own recursive child node

fsNode = fsNode.nodeSubdirectory();

The SAP NetWeaver Webdynpro Java is a technology used to build


user interfaces.Which are portable across all the platforms.As
we know that programming is based on Java code.The Webdynpro framework
generates most of the code,our job is just to write the business logic
which is required.Here i would like to explain the various extension
points where the custom code is written in webdynpro.In Webdynpro
basically there are two types of controllers.They are View controller and
Component Controller.To write the effective coding ,a webdynpro java
programmer must know each and every methods present in the above controllers

==========================
Methods In View Controller
==========================

<1> wdDoInit()

This is the hook method present in the each controller.This code


basically called only once per the life cycle.In this method we initialize all
the resources utilized by the View Controller

<2> wdDoExit()

This is also a hook method present in the all controllers.If at all


any resources are acquired at the time of initialization(defined in wdInit()
method),all the resources must be cleared here.This method is called immediately
before the controller lifecycle may come to end.

<3> wdDoModify(IPrivate<view-name> wdThis,IWDContext wdContext,IWDView view,boolean


firstTime)

This method is call ed every time before rendering the screen.This method
is the only place to modify the existing view elements or to create a new elements.
The various UI elements i the screen you can access by the parameter view.
For Example if you want to access TextFied which is present in the screen
//code
IWDTextField inputField=(IWDTextField)view.getElement("id of the text field");
//code end
In this method you can also access the context of the view controller using
the variable wdContext.The current class reference is the first parameter that
is wdThis.By using this you can enable or disble the various actions,to fetch the
component context ,you can fire the plugs and you can call any methods present
in this view controller.
The fistTime boolean parameter indicates that wether the screen is rendering for
the first time or not.

<4> wdDoBeforeAction(IWDBeforeAction action)


This method is used just to do some additional validations of user input

==============================
Methods in ComponentController
==============================

<1> wdDoInt()
This method is a hook method present in all the controllers.In this method
we usually initialize the resources required for the component controller class.
This method called only once in the component lifecycle.

<2> wdDoExit()
This method is a standard hook method in the controller.If at all any resources
are acquired in the initialization process,all the resources will be released in this method.
This method is called when component life cycle may come to end.

<3> wdDoPostProcessing(boolean isCurrentRoot)


This method is used to implement cross component data validation.In webdynpro applications
the data from multiple components must be validate before the next step is taken.This method usually
consists of cross component data verification.

<4> wdDoBeforeNavigation(boolean isCurrentRoot)


This method is basically used to give prioritizations to navigation events.
Incase if each view controller is fired an outbound plug,a navigation event is fired .
Suppose in a vie set all views fires an outbound plug then all navigation events are
placed in to a queue and are only processed once all the views in the current assembly
have been processed.This method is called just before the webdynpro frame work processes
the events in your navigation queues.This allows you to implement your own coding to do
such things a navigation event prioritization etc.

About isCurrentRoot parameter


-----------------------------------------
When component's interface view is nominated to be the initial screen by the user
then the component containing that interface view is known as the root component.Since the
wdDoPostProcessing() method can be found in all component controllers,it is necessary to
identify whether the current invocation occurs in the component controller of root component
or not.

Supply Function in Webdynpro


Supply function principles:

- A supply function is used to populate an entire node collection.

- Any context node may have a supply function defined for it.

- All singleton nodes must have a supply function defined.

- The existence of a supply function is defined declaratively.

- A supply function is called automatically by the Web Dynpro Runtime when an attempt is made to read an
empty node collection

- A node collection could be empty node collection

- A node collection could be empty for any one of the following 3 reasons.

1. It has never been populated before.

2. The lead selection in the parent node collection has changed.

3. Application coding has explicitly invalidated the element collection.


Why are supply function needed?

- A supply is needed primarily to populate a singleton node's element collection.

- However if required, any context node can have a supply function defined for it.
Singleton Nodes

 It is very important to remember the difference in runtime behaviour between a singleton node and a non-singleton
node. When a node is declared to be singleton, there will only ever be only one instance of that node-irrespective of
the number of elements found in the parent node's element collection. This is not the case for the non-singleton node.
In this case, there will be as many instances of the non-singleton child nodes as there are elements in the parent
node's element collection.
 The significant point here is that when the lead selection in the parent element collection changes, the contents of the
singleton child node become invalid. Consequently, the next time data is required from the singleton child node, the
entire element collection must be rebuild in order that it match the data in the newly selected parent element.
 The task of rebuilding singleton child node must be performed by a dedicated supply function.
 singleton node is related to its parent node collection.

why do singleton node exists?

When a typical business transaction is being used, information will often be presented in the form of a list of header
records of some sort; for instance, sales order headers. From this list, the user will typically select one order header
and then look at its line items. It makes much better sense to read the line item information only when it is needed,
rather than to read all the line items for all the sale orders in the hope that the user PLJKW want to look at the
information! This would be a highly inefficient application architecture both in terms of processing requirements and
memory usage.When a typical business transaction is being used, information will often be presented in the form of a
list of header records of some sort; for instance, sales order headers. From this list, the user will typically select one
order header and then look at its line items. It makes much better sense to read the line item information only when it
is needed, rather than to read all the line items for all the sale orders in the hope that the user PLJKW want to look at
the information! This would be a highly inefficient application architecture both in terms of processing requirements
and memory usage.
To know more about supply functions, refer to
Validating Web Dynpro Java applications

Validating data is one of the implicit requirements of any applications. When dealing with mission critical and realtime
data one has to validate data before proceeding because user can provide any thing as input. I was searching on the
SDN forum and noticed that there are very few posts that cater different requirements for validation, so I thought of
writing one blog on this topic.

Web dynpro provide generic UI services to validate and display messages of different types in the web browser. Web
dynpro event model is based on event abstraction called action when ever user clicks on a button it fires an event on
server, which is handled by the action associated with onclick event of that button. There are two different types of
actions, called validating actions and non-validating actions. Validating actions are those which cannot be executed
when the generic validation services, we'll discuss it shortly, produce errors. Non-validating actions are executed
regardless of what generic validation services produce.

Web dynpro provide two types of validations one is gneric validation controlled by web dynpro framework and other is
custom validation. Web dynpro automates the behaviour, aka generic Validation, for validating data against the data
type selected for the data field. For example, you have selected date type for Birthday field and enters invalid data
like MyBirthday, it will inhibit the execution of the event handler and display an error message to the end user. After
correcting the invalid data, you can press the Save button again. Generic validation services only validates data
aginst the type selected, which is also applicable for Simple Types you create.

With Custom validation you can validate data against your business rules and conditions. If you wish to write view
specific validation rules then refer to A Simple Form example. This blog discusses how to write validation that provide
validation for multiple views in an application.

Step 1:

We will first define the error messages to be displayed when an error occurs. Double click on Message Pool from
Web Dynpro components tree. Define following messages:

Message Message Type Message Text


Key

requiredInput error {0} is required, please enter valid value.

invalidDate error {0} is invalid, please enter date in valid format i.e.
mm/dd/yyyy.

Step 2:

Create new Custom Controller called Validator and add methods as shown below:

public void checkDate (com.sap.tc.webdynpro.progmodel.api.IWDNodeElement nodeElement,


com.sap.tc.webdynpro.progmodel.api.IWDAttributeInfo attributeInfo,
java.lang.String fieldLabel, java.sql.Date attributeValue, boolean checkRequired )
{
//@@begin checkDate()
if (checkRequired) {
checkRequired(nodeElement, attributeInfo, fieldLabel, attributeValue == null ? "":attributeValue.toString());
}
IWDMessageManager msgMgr = wdComponentAPI.getMessageManager();
if (attributeValue != null && attributeValue.before(new Date(System.currentTimeMillis()))) {

msgMgr.reportContextAttributeMessage(nodeElement, attributeInfo, IMessageOOMS.PAST_DATE, new


Object[] { attributeValue, fieldLabel }, true);

}
//@@end
}
//@@begin javadoc:checkRequired()
/** Declared method. */
//@@end
public void checkRequired(com.sap.tc.webdynpro.progmodel.api.IWDNodeElement nodeElement,
com.sap.tc.webdynpro.progmodel.api.IWDAttributeInfo attributeInfo,
java.lang.String fieldLabel, java.lang.Object attributeValue )
{
//@@begin checkRequired()
IWDMessageManager messageMgr = wdComponentAPI.getMessageManager();
if (attributeValue instanceof String) {
if (((String) attributeValue).length() == 0) {

messageMgr.reportContextAttributeMessage( nodeElement, attributeInfo,


IMessageOOMS.REQUIRED_INPUT, new Object[] { fieldLabel}, true);

}
}
//@@end
}

Step 3:
Now create a view called FormView assign the controller created in step 2 to the view. Add two context value
attributes name and birthday of type string and date respectively. Create a form as shown in the figure below:

Add following code to Action mapping of save button.

public void onActionSave(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent )


{
//@@begin onActionSave(ServerEvent)
wdThis.wdGetValidatorController().checkRequired(wdContext.currentContextElement(),
wdContext.getNodeInfo().getAttribute(wdContext.currentContextElement().NAME), "Name",
wdContext.currentContextElement().getAttributeValue(wdContext.currentContextElement().NAME));
wdThis.wdGetValidatorController().checkDate(wdContext.currentContextElement(),
wdContext.getNodeInfo().getAttribute(wdContext.currentContextElement().BIRTHDAY), "Birthday", (Date)
wdContext.currentContextElement().getAttributeValue(wdContext.currentContextElement().BIRTHDAY), true);
wdComponentAPI.getMessageManager().raisePendingException();
wdComponentAPI.getMessageManager().reportSuccess("The sample form data was successfully saved!");
//@@end
}

Finally build your project, deploy it and try the custom validator. If you want to add validation to another view just
repeat the Step 3 for that view

FAQ - Models - Adaptive RFC Questions

General

JCO Connectivity to RFCs?

Each WebDynpro application that connects to RFCs has to maintain RFC Connections. The general steps for
handling RFCs are as follows:

1. Create WebDynpro Project


2. Import RFCs using Adaptive RFC Model
a. Specify the Model name, package
b. Specify the "Default Logical Name for model instances" and "Default logical names for RFC
metada"
c. Specify the backend connectivity details like hostname, system number, client, logon
userid,password
d. Select the RFCs you want to import
3. Modify the WebDynpro project/application as per your requirements
4. Go to WebDynpro Content Administrator
(http://<server_host>:50000/webdynpro/dispatcher/sap.com/tc~wd~tools/Explorer) and configure the JCO
connections (created in step 1.2) which were created for your project when you imported the Adaptive RFC
Model.
5. Check and ensure that your JCO connections are working.
6. Build and deploy the WebDynpro Application.
back to top

What is difference between modeldata destination and metadata destination?

Model data destination will fetch actual data while metadata destination will contain descrition of the data.

back to top

How to import Adaptive RFC Model?

Detailed information can be found in step-by-step tutorial 'Accessing ABAP Functions'.

1. Choose the context menu entry Create Model on the Models node of the relevant Web Dynpro component.
2. In the model wizard, choose Import Adaptive RFC Model followed by Next.
3. Make the required entries - for example, to specify where the generated RFC model instances and RFC
metadata are to be stored. You do not have to use an existing model package, as you can create a new one
in the wizard. For the logical dictionary, you generally enter a new name for each model. The default
package name for the dictionary types is <myModelPackage>.types.
4. In the next wizard window, you enter your user data for the SAP System that contains the BAPIs from which
you want to generate the proxies. You use it to log on to the SAP System online.
5. To be able to log on to the SAP System, it must be entered in the logon group.
6. The tool SAP Enterprise Connector is started. Select the BAPIs for which you want to create Java proxies in
a generation process. Then choose Next to proceed to the next wizard window.
7. The import log provides information about the generated model classes, properties, and model relations.
Choose Finish to start the generation process.
8. Don't forget to instanciate a model object class for each input context node and to bind it to it's parent.

9. //This line is generated by Service Controller Template for you

10. wdContext.node<RFC_Name>_Input().bind(new <RFC_Name>_Input());

11. //This line has to be coded by you for all input child objects

12. //Create instance of a model object class for each input context node and bind it to it's parent

13. wdContext.current<RFC_Name>_InputElement().modelObject().set<ChildInputNode>(new <ModelClass for


ChildInputNode>());

Troubleshooting

Troubleshooting JCo and AdaptiveRFC in Web Dynpro for Java


 Note 947376 - Troubleshooting JCo (used by AdaptiveRFC in Web Dynpro for Java) connection issues
 SDN Article Adaptive RFC Troubleshooting Guidecovering possible issues on JCo, aRFC and Web Dynpro level.
Includes some links.
 You may output the model data, e.g. useful when nothing is visible and debugging disallowed. Simply use one of
the wdContext.currentOutputElement().modelObject().toXml() methods and write data to log or message manager.
 In case the called BAPI does not give the same results when called via aRFC as when called directly in SAP
GUI using transaction SE37, possible causes are:
o You want data that stands in a BAPI parameter of type table: Check that you did not use the table model node that is
a silbing of the output node (has to role of input parameter), but that is a child of the output node (has a role as output
parameter and hence contains the desired data).
o An input parameter may require a fixed length (called "internal format") that is ensured by SE37 automatically but not
by aRFC. Note: The output (called "external format") is truncated for SE37 and aRFC, so using aRFC you may not
use the same value as input as you get as output...
Procedure: Set an external break point in SE37 (click on one of the first lines of code and press CTRL+SHIFT+F9).
Now check the value of all import parameters by double clicking them - they have to be exactly identical when called
from WDJ via aRFC and from SE37, including leading spaces or zeros (may have beed added by SE37 tester
automatically) as they may be relevant. In case you find such a difference, the quickest way to test whether this is the
reason is to modify the variable value in ABAP debugger when called from WDJ by clicking the pencil icon next to the
variable name, change the value, pressing ENTER, and pressig CONTINUE-button.
In case you need to change from external to internal format, you may use the following sample code for material ID
(German: Artikelnummer):

o try {

o //If material ID is a number, it must (!) be delivered in internal formatting (18 chars)

o new Integer(wdContext.currentPi_Mat_SelectionElement().getMaterial());

o while (wdContext.currentPi_Mat_SelectionElement().getMaterial().length()<18) {
o wdContext.currentPi_Mat_SelectionElement().setMaterial("0".concat(

o wdContext.currentPi_Mat_SelectionElement().getMaterial()));

o }

o } catch (NumberFormatException e) {

o //If material ID contains characters, internal formatting leads to zero search results, so keep

o //external formatting (output of all function modules is always external format, so we already have it).

o }

Check all Users who have logged into portal - webdynpro appl

Get Portal users from WebDynpro

//Get user Logon Id who has logged in the current session-I

To run this code successfully, we need to add security.api.jar file by using following setps
Right Click on project->Java Build Path>Add Variables>WD_Runtime>Extendsàcom.sap.security_2.0.0>lib-
>com.sap.security.api.jar
public void GetLogonID()

Unknown macro: {//@@begin GetLogonID()String LogonID;try{ /* create an user object from the current user */
IWDClientUser wdUser=WDClientUser.getCurrentUser(); IUser user=wdUser.getSAPUser(); if(user!=null)
{ IUserAccount acct=user.getUserAccounts()[0]; if(acct!=null) LogonID=acct.getLogonUid(); else LogonID="acct
null"; }

else

Unknown macro: { LogonID="user null"; }

wdComponentAPI.getMessageManager().reportSuccess(user.getFirstName()+" "+user.getLastName());
wdComponentAPI.getMessageManager().reportSuccess(LogonID.toUpperCase());
}catch(Exception e)

Unknown macro: { e.printStackTrace(); }

//@@end
}
//@@begin javadoc:GetCurrentUser()
/*Declaredmethod./
//@@end

*Get user who has logged in the current session-II{*}public void GetCurrentUser()

Unknown macro: {//@@begin GetCurrentUser()String LogonID;try{ // create an user object from the current user
IWDClientUser wdUser=WDClientUser.getCurrentUser(); IUser user=wdUser.getSAPUser();
LogonID=user.getUniqueName(); wdComponentAPI.getMessageManager().reportSuccess(user.getFirstName()+"
"+user.getLastName()); wdComponentAPI.getMessageManager().reportSuccess(LogonID.toUpperCase()); }

catch(Exception e)

//@@end
}
//@@begin javadoc:CheckAllUsers()
*Declaredmethod ./
//@@end
//Check all the users method to get current logged in users from the portalpublic void CheckAllUsers(){
//@@begin CheckAllUsers()
IWDClientUser currentUsers[]=WDClientUser.getClientUsers();
//Displaying the count of logged on users
wdComponentAPI.getMessageManager().reportSuccess("Number of logged on Users in the portal - "+
(currentUsers.length-1));
for(int i=0;i<currentUsers.length;i++)

Unknown macro: {if(currentUsers[i]!=null){ // Displaying the logged on users; if(!


currentUsers[i].getLastName().equals("Guest")){ String first= currentUsers[i].getFirstName();
wdComponentAPI.getMessageManager().reportSuccess("User - "+currentUsers[i].getFirstName()+"
"+currentUsers[i].getLastName()); }

}
}

//@@end
}
//@@begin javadoc:LogOffUser()
/*Declaredmethod./
//@@end
Log off the userpublic void LogOffUser(){
//@@begin LogOffUser()
WDClientUser.forceLogoffClientUser("http://koldxp-pigoswam:50000/irj/portal");
//@@end
}

Retrieving all iViews from PCD

iview.java

Recently there was a series of forum postings, as how to retrive retrive iViews from PCD (Portal Content Directory). I
think this wiki will help answer to that questions and also will put an end to further silimar postings.

In this Wiki i have posted the code to retrive iViews, Pages and Workset's from the PCD.

Copy and paste the below piece of code in NWDS and add appropriate jar files in the classpath to run the application

public List getPCDContents(IPortalComponentRequest request)throwsException

try{Hashtable env =newHashtable();

env.put(IPcdContext.SECURITY_PRINCIPAL, request.getUser());

env.put(Context.INITIAL_CONTEXT_FACTORY,IPcdContext.PCD_INITIAL_CONTEXT_FACTORY);

env.put(com.sap.portal.directory.Constants.REQUESTED_ASPECT, PcmConstants.ASPECT_SEMANTICS);
InitialContext ctx =null;

DirContext dirCtx;

List iViewList =null;

ctx =newInitialContext(env);

dirCtx = (DirContext) ctx.lookup("pcd:portal_content/");

PcdSearchControls pcdSearchControls = newPcdSearchControls();

pcdSearchControls.setReturningObjFlag(false);

pcdSearchControls.setSearchScope(PcdSearchControls.SUBTREE_WITH_UNIT_ROOTS_SCOPE);

dirCtx.addToEnvironment(Constants.APPLY_ASPECT_TO_CONTEXTS,Constants.APPLY_ASPECT_TO_CONTEX
TS);

NamingEnumeration ne =

dirCtx.search("","(com.sap.portal.pcd.gl.ObjectClass=com.sapportals.portal.iview)",cdSearchControls);

iViewList =

newArrayList();

while(ne.hasMoreElements())

{IPcdSearchResult searchResult = (IPcdSearchResult) ne.nextElement(); String location = "pcd:portal_content/" +


searchResult.getName(); //Get the full pcd path of the iview. iViewList.add(location); } returniViewList;}

catch(Exception e )

{ throw newException(e);}

For retriving Pages from PCD

page.java

In the previous code change the line_ NamingEnumeration ne =

dirCtx.search("","(com.sap.portal.pcd.gl.ObjectClass=com.sapportals.portal.*iview*)",pcdSearchControls); to :
NamingEnumeration ne =
dirCtx.search("","(com.sap.portal.pcd.gl.ObjectClass=com.sapportals.portal.*page*)",pcdSearchControls);

to:

NamingEnumeration ne = dirCtx.search("","(com.sap.portal.pcd.gl.ObjectClass=com.sapportals.portal.

page)",pcdSearchControls);

For retriving Worksets from PCD

workset.java

NamingEnumeration ne =
dirCtx.search("","(com.sap.portal.pcd.gl.ObjectClass=com.sapportals.portal.

iview)",pcdSearchControls);

to:

NamingEnumeration ne = dirCtx.search("","(com.sap.portal.pcd.gl.ObjectClass=com.sapportals.portal.
workset)",pcdSearchControls);

If you have any further queries please feel free to leave a comment or mail me.

Note: There is a similar type of PDF document but that code will only get the iviews but the above code will get iviews
and also if needed properties of iviews also.

Configure NWDS for Debugging

Procedure:

1) Open NWDS(Netweaver Developer Studio).

2) Go to

Window > preferences > SAP Enterprise Portal

and add host name,port and alias of each EP instance in which you wish to connect to Netweaver Developer Studio.

A valid UserId and Password must also be supplied.

3) Now to Configure Remote Java Application debug settings

Create new Remote java application debug settings.

4) In NWDS goto

Debug > Remote Java Application

and create new setting for your current Portal Application project.

5) Give the portal IP address and debug port specified in config tool,default port is 50021.

Note: Make sure that portal application is already deployed in the Portal.

6) The export function allows an option to include the source code of the project in the PAR file.

7) If the connection is attached to J2EE engine,NWDS is ready for debugging.

view

Confirmation dialog box (lightwight popup) in Web Dynpro Java


Motivation

Before performing some operation you want a confirmation from the user that he/she really wants to complete the
task (e.g. navigate away without saving changes). Ask the user by means of a confirmation dialog box. A standard
lightwight popup sufficiates for this simple task; hence, no custom window, destroyment, message area
disabler/enabler etc. for popup is requried.

Required elements

You need a confirmation window (created upon your order by a factory) with some texts (defined by yourself) and at
least one button (defined by yourself). Furthermore, you need at least one event handler (created by yourself) to
make the button work.

Step by Step

First, create one EventHandler for each button. Open tab "Methods", click "New", choose type "EventHandler", enter
a name (e.g. GoHome_Canceled and GoHome_Confirmed), click "Finish". Go to tab "Implementation", go to the
method(s) just created, add a short meaningful JavaDoc and implement the activities to be performed.

Second, if creating an international application, add the texts to the MessagePool so they can be translated with
ease. See screenshot for example setting of Message Key and Type.

Third and last, add the following coding for the popup into the onAction-method of the button where you require the
confirmation from the user (or whereever you want to call the popup). Don't forget to perform OrganizeImports after
pasting.

//START: lightwight popup window

IWDControllerInfo controllerInfo = wdControllerAPI.getViewInfo().getViewController();

//let factory create window with first button

IWDEventHandlerInfo evtHndlr = controllerInfo.findInEventHandlers("GoHome_Canceled"); //<-- Name of event


handler, has to match exactly, see step 1 / Methods tab

IWDConfirmationDialog confDialog = wdComponentAPI.getWindowManager().createConfirmationWindow(

/* dialogText, evtHndlr, buttonText OR evtHndlr.getName() */


wdComponentAPI.getTextAccessor().getText("GoHomeConfQuestion"),

evtHndlr,

wdComponentAPI.getTextAccessor().getText("GoHomeConfCancel")

);

//add optional second (or 3rd, 4th,...) button

evtHndlr = controllerInfo.findInEventHandlers("GoHome_Confirmed"); //<-- Name of event handler, has to match


exactly, see step 1 / Methods tab

confDialog.addChoice(evtHndlr, wdComponentAPI.getTextAccessor().getText("GoHomeConfConfirm"));

//align and display window

confDialog.setTitle(wdComponentAPI.getTextAccessor().getText("GoHomeConfTitle"));

confDialog.setWindowPosition(WDWindowPos.CENTER);

//confDialog.setWindowSize(90,90); //set window size in pixels

confDialog.show(); //replaces deprecated confDialog.open();

Dynamic UI Generation in Web Dynpro for Java

The Web Dynpro programming model enables you to create contexts, view layouts, and actions - not only at
design time, but also dynamically at runtime (dynamic programming). However, you should only avail of
dynamic creation of user interface elements, context attributes, and actions if these are not known at design
time since the error possibilities and ability to maintain the program code to be implemented are much higher.

Displaying a subset of user interface elements

If at design time it is known which UI elements can possibly be displayed to the user, but you don't want to
display them all at once, there is a way to avoid the use of dynamic user interface generation: use the element
property visible.

Every UI element has a property called visible. At design time, it can set to either NONE, BLANK or
VISIBLE(default), but it also can be bound to a context element of type WDVisibility. If you add an attribute of
type WDVisibility (com.sap.ide.webdynpro.uielementdefinitions.Visibility) to your context, this gives you a lot of
control over the view's layout at runtime. Bind each element of a group of elements you want to display at the
same time in a view to a context element with type WDVisibility, and set the value of this attribute to either
NONE, BLANK or VISIBLE to control the visibility of that group. The elements are effected this way:

VISIBLE: the element is visible to the user


NONE: the element is not visible to the user, there is no space taken up
BLANK: the element is not visible to the user, but the space it would take up when visible is preserved

Use case:
You have a TextEdit element with an "edit"-button while it is in read-only mode. When the user clicks on "edit",
you want to make the TextEdit element writable, but you also want to hide the "edit"-button and display two
buttons to "save" and "cancel" the changes. Here you need two context attributes of type WDVisibilty, one for
each state of the TextEdit element, and bind "edit" to one of them and "save" and "cancel" to the other. At
design time, all three buttons are on the view, but only the context attribute of the "edit"-button is set to
WDVisiblity.VISIBLE, the others are set to NONE. In the ActionEventHandler methods of the buttons, you can
now always switch the states of those context elements. That way, you always have the required buttons
displayed while not having to implement any fancy coding.

Creating UI elements at runtime

In every Web Dynpro view controller, the method wdDoModifyView is implemented; it is called by the Web
Dynpro runtime environment for modification of the view layout. For all visible views, this takes place at a time
immediately before the closing response rendering. This method is the only place where you should alter the
view layout!

wdDoModifyView contains the following parameters:

firstTime of the type boolean: This is true only if wdDoModifyView wis called for the first time during the life cycle
of the corresponding view.
view: Reference to the layout controller of the view.
wdThis: Reference to the IPrivate interface of the view controller . wdThis allows access to the controller
context; it also allows triggering outbound plugs and events and access to action objects as well as controllers
used.
wdContext: Reference to the root context node of the view controller (for the current context).

To add an element to the view, you must first create a new element and then "attach" it to an existing element
(for example the "RootElement" Container) of the view. You can then also apply the same settings to this
element that you can apply to a UI element at design time. Creating and attaching a new element could look like
the following:

public static void wdDoModifyView(IPrivateDynamicUIGenerationView wdThis,


IPrivateDynamicUIGenerationView.IContextNode wdContext,

com.sap.tc.webdynpro.progmodel.api.IWDView view, boolean firstTime)

//@@begin wdDoModifyView

if(firstTime){

IWDTransparentContainer root = (IWDTransparentContainer)view.getRootElement();

IWDButton bt1 = view.createElement(IWDButton.class, "buttonUp");

bt1.setText("Up");

root.addChild(bt1);

//@@end

}
As you can see, we first got a reference to the RootElement Container, then created the new Button with the id
"buttonUp", set an attribute (setText = "Up") and finally attached it to the RootElement Container. We also used
the boolean variable firstTime, because we only wanted to create the UI element once the view is created. As
wdDoModifyView is executed with every roundtrip, the creation of UI elements has to be controlled somehow.
Another way to do that would be to introduce an own, global boolean variable to have more control over UI
element creation. If you need to redraw the dynamically created elements for any reason (for example if the
amount changes based on input data and the user can input the data again at any time), you can reset the view
to its state at design time and then create the UI elements again - but as creating them with every round trip
would lead to bad performance, you should only do that when it is needed; use the boolean variable for that and
reset the view with

view.resetView();

Binding dynamically created UI elements to the context

Some elements must be bound to the context in order to work properly, for example the InputField UI element.
When those elements are created at runtime, they must be bound to the context at runtime as well, which often
results in the creation of that context at runtime. But as the method wdDoModifyView is only to be used for the
alteration of the view and not the data, the context creation should take place somewhere else - a good place is
always the action handler method in which the creation of all dynamic content is decided.

Web Dynpro for Java provides very simple methods to access and modify the context. You can access each
node's metadata and add or remove attributes from it, you only need to provide the new attribute's name and
datatype. Inserting values to dynamically created attributes is equally simple: although you do not have the
setter-methods that you would get for attributes declared at designtime, all you need is the name of the attribute.
The following code shows an example of a created attribute which is then filled for the current element:

for(int i = 0; i < 5; i++){

wdContext.nodeValue().getNodeInfo().addAttribute("value" + i, "ddic:com.sap.dictionary.integer");

wdContext.currentValueElement().setAttributeValue("value" + i, i);

As each attribute's name must be unique within a node, there is a variable appended to its name in this case.
For the datatype there are 3 possible paths:

a Java class (prefixed with "java:")


a type in the local Java DDIC (prefixed with "ddic:")
a type from a logical dictionary (in that case the name is built "extern:name.of.logical.dictionary:name.of.type")

If you choose a Java class, no UI element can be bound to this attribute! A DDIC type may be either one that
you defined within your application or one of the predefined types (those you can pick from the dropdown list of
the properties of attributes created at design time). Note, that the predefined types are in the package
"com.sap.dictionary" at runtime.
If the type is Model based, consider retrieving the type from the Model metadata and using addAttribute(String,
IDataType) instead of addAttribute(String, String), especially if it is a CMI model.

Examples for datatype declarations:

java:java.util.Map
ddic:com.sap.dictionary.string
extern:com.sap.test.types.Flight:com.sap.test.types.BAPIRET2

Dynamically creating actions, parameter mapping

You can create UI elements at runtime together with a corresponding action, which is a requirement for some
elements to work properly, for example pushbuttons. As it is not possible to dynamically create event handlers in
the view controller, dynamically created actions must use an event handler declared already at design time.
Mapping an event parameter from the event source (the user interface element) to the signature of the event
handler in the view controller is termed as Parameter Mapping in the Web Dynpro.

If you only need one action, it can be created at design time and be assigned to all your elements at runtime. In
case the enabling state of elements using the same event handler should be different, you need to create
several actions, which can be done at runtime.

public static void wdDoModifyView(IPrivateDynamicUIGenerationView wdThis,


IPrivateDynamicUIGenerationView.IContextNode wdContext,

com.sap.tc.webdynpro.progmodel.api.IWDView view, boolean firstTime)

//@@begin wdDoModifyView

if(firstTime){

IWDTransparentContainer root = (IWDTransparentContainer)view.getRootElement();

IWDButton bt1 = view.createElement(IWDButton.class, "buttonUp");

//

IWDAction theAction =
wdThis.wdCreateAction(IPrivateDynamicUIGenerationView.WDActionEventHandler.BUTTON_PRESSED,"");

bt1.setOnAction(theAction);

//

bt1.setText("Up");

root.addChild(bt1);

//@@end

It is also possible to assign an ID to the action with the method wdCreateNamedAction(WDActionEventHandler,


String, String). As mentioned before, the ActionEventHandler must be created at design time, in the example it
is called "ButtonPressed". If you now have multiple elements assigned to one ActionEventHandler, you must
determine the action to be performed by another parameter within the ActionEventHandler. At design time, the
ActionEventHandler "ButtonPressed" has been supplied with a parameter "buttonID" of type String. With
parameter mapping it is possible to supply the ActionEventHandler with the current button's ID by mapping a
value of type String to the method:

public static void wdDoModifyView(IPrivateDynamicUIGenerationView wdThis,


IPrivateDynamicUIGenerationView.IContextNode wdContext,

com.sap.tc.webdynpro.progmodel.api.IWDView view, boolean firstTime)

//@@begin wdDoModifyView

if(firstTime){

IWDTransparentContainer root = (IWDTransparentContainer)view.getRootElement();

IWDButton bt1 = view.createElement(IWDButton.class, "buttonUp");

IWDAction theAction =
wdThis.wdCreateAction(IPrivateDynamicUIGenerationView.WDActionEventHandler.BUTTON_PRESSED,"");

bt1.setOnAction(theAction);

//

bt1.mappingOfOnAction().setString("buttonID", bt1.getId());

//

bt1.setText("Up");

root.addChild(bt1);

//@@end

Since NW 7.1, the methods addParameter of IWDParameterMapping are deprecated, use the following
methods instead, depending on the parameter type:

setBoolean(String name, boolean value)


setByte(String name, byte value)
setChar(String name, char value)
setDouble(String name, double value)
setFloat(String name, float value)
setInt(String name, int value)
setLong(String name, long value)
setShort(String name, short value)
setString(String name, String value)

The parameter name refers to the action parameter name. That way additional information is sent to the
ActionEventHandler by mapping a constant value to one of the parameters, giving you the opportunity to decide
on the next actions. If you want to use an existing event parameter, you can use the following method instead:

addSourceMapping(String sourceName, String newName)

In this case, sourceName is the name of the existing event parameter and newName is the action parameter
you want to map to.
Action Handling

As previously mentioned, the ActionEventHandler method has to be created at design time. Following the
information on this page, you should have one method that can be accessed by all elements, while the
additional parameter helps to determine what action has to be taken next. With a simple if/else-block, you can
implement all the functionality you would usually implement in different ActionEventHandler methods.

Dynamically Building the Context

For dynamic creation of the context belonging to the input fields, the standard method wdDoInit() of the (View/
Component / Interface ) Controller is suitable since this method is executed as soon as the controller is instantiated.
Another advantage of the method wdDoInit() is that it is executed only once during the life cycle of the view.
Value attributes and value nodes can be dynamically created in the controller context, the interface IWDNodeInfo
provides the following methods:

? addAttribute( java.lang.String name, java.lang.String dataType)

? addAttribute( java.lang.String name, com.sap.dictionary.runtime.IDataType dataType)

? addChild( java.lang.String name,


java.lang.Class elementClass,
boolean singleton,
boolean mandatory,
boolean multiple,
boolean mandatorySelection,
boolean multipleSelection,
boolean initializeLeadSelection,
java.lang.String dataType,
IWDNodeCollectionSupplier supplier,
IWDNodeCollectionDisposer disposer)

//Dynamically create a context node

IWDNodeInfo node = wdContext.getNodeInfo().addChild( "DynamicNode", null, true, true, false, false, false, true, null,
null, null);

//Dynamically add attributes to the context node

nodeInfo.addAttribute("CustomerName", "com.sap.dictionary.string");

nodeInfo.addAttribute("CustomerID", "com.sap.dictionary.string");

nodeInfo.addAttribute("CustomerAddress", "com.sap.dictionary.string");

nodeInfo.addAttribute("PurchaseOrderNumber", "com.sap.dictionary.string");
Parameters:
name - the name of the child NodeInfo. Must be unique all over the context.
elementClass - The element class for a model node, null for a value node.
singleton - indicates, whether the described Node is singleton relatively to its parent
mandatorySelection - indicates, whether the selection of the described Node is guaranteed to have at least one
*element
multipleSelection - indicates, whether the selection of the described Node may contain more than one element.
mappedPath - The path of the mapped node or null if you want to set the origin node later.
selectionMapped - indicates whether the selection is mapped
initializeLeadSelection - indicates whether the lead selection is to be set to 0 if the collection is filled
dataType - the name of a data type, a data type (IStructure) or null.
supplier - A supply "function". May be null, in that case the elements remain empty and must be set manually during
an event handler.
disposer - A dispose "function". May be null if no application code is needed before deletion of the node.

Creating tables in SAP Interactive Forms using Wed Dynpro:

1. Create a node <DataSource> with cardinality 1:1.

2. Create child node<TableWrapper> of <Datasource> of cardinality 1:n.


3. Now put the actual data node in <TableWrapper >.
Fig2. Table in Interactive Form

4. Now on the form add buttons as shown in fig.2


5. Write the following code in the click event of button <Add Item>:

BP.Table1.Row1.instanceManager.addInstance(1);
xfa.form.recalculate(1);

6. Write the following code the click event of button<X>.

BP.Table1.Row1.instanceManager.removeInstance(this.parent.index);
WebDynpro Java and IFbA - dynamically integrate images in forms

How to use the Image Field control in an IFbA

I was trying to integrate an image dynamically in my Interactive Form and it took me more than one day to find a
proper solution to get the thing running and to set the image field to readonly. So that's why I thought it's worth to
write an article in wiki about it. The Image Field control was always editable and you could simply replace the image
by another one. Sometimes this behaviour isn't desired at all and in my case I wanted to have the control readonly.

Step by step: integrate the Image Field and set it to readonly


1. Define a String attribute e.g. "url" in your WebDynpro View Context (node which is mapped as the
DataSource of your IFbA)
2. Copy the images you wanna include in your form to the folder: Resources/src/Components/ Your
Component Name
3. Map the url of your image to your View Context. In order to do that you can use the following code snippet
e.g. in the wdDoInitMethod of your View:
4. String url = "";
try {
url = WDURLGenerator.getAbsoluteWebResourceURL(wdComponentAPI.getDeployableObjectPart(),
"saplogo.gif");
} catch (WDURLException e) {
// proper exception handling
e.printStackTrace();
}
IWDResource resource =
WDWebResource.getWebResource(
wdComponentAPI.getDeployableObjectPart(),
WDWebResourceType.GIF_IMAGE,
"saplogo.gif");
wdContext.currentDataSourceElement().setUrl(url);
5. Edit your InteractiveForm element (Lifecycler Designer)
6. Add an Image Field control to your form
7. Map the url attribute defined in step 1 to the URL attribute of your image field (see picture below)

8. Select your Image Field and add some scripting to the following events (Language: JavaScript, Run At:
Client):
 form:initialize event: this.value.image.href = xfa.resolveNode(this.value.image.href).value;
 form:ready event: this.access = "readOnly";

Result: As described in step 4 you can simply choose programmatically which picture should be displayed on the
form. As a result of the scripting for the form:ready event the Image Field is now set to readonly and it is not longer
possible to click on the image in order to replace it by another one.

Using Table Cell Variants in NW 2004s


Goal: Change the table cell editor for a column in the selected row.

Remark: If you want to use CellVariant for readOnly tables with alternating design, you shall have NW 7.0 SP15
WebDynpro Patch 10 (see note number 1138102) for nice formatting.

Hi,

"How to change the cell editors for one column at runtime using Table Cell Variant table standard cell"; this is the
question I found many times in forums. In recent times I had been working on Table cell Variants and this wiki is
about the usage of Table Cell Variants.

Create a simpletype "sex" with Enumeration with Male and Female

Create a Context Node "TableData" with following four attributes:

Attribute Name Attribute type

1. no String
2. name String
3. sex Sex(Simpletype)
4. variant String
Make the variant attribute property *calculated=true*

Bind the "TableData" node to Table.!image5.JPG!

Click Next, change the editor value for sex field to TextView.

Now, switch to Layout Tab and give column Property Selectedcellvariant=TableData.variant.

Create a new element "Insert cell variant" by right clicking on table column name.
*Select TableStandardCell as Type*

Give the UI element Property variantkey=variant1.


Insert Cell editor for the TableStandarCellvariant.
Select InputField as an editor.

Give the Input field UI element Property value=TableData.name.


Repeat the same steps for sex column. Insert cell variant TableStandardCell property variantkey=variant1,

insert editor Dropdownbykey and bind UI property value selectedkey= TableData.sex.

Now finally, switch to Implementation Tab

Write the following code in wdDoInit()

public void wdDoInit()

//@@begin wdDoInit()

String no[]={"1","2","3"{color:black}};

String name[]={"naga","raju","meesala"{color:black}};

String sex[]={"Male","Male","Male"{color:black}};

for(int i=0;i<no.length;i++){

IPrivateTableSelectView.ITableDataElement tableElement=wdContext.createTableDataElement();

tableElement.setNo(no[i]);

tableElement.setName(name[i]);
tableElement.setSex(sex[i]);

tableElement.setVariant("");

wdContext.nodeTableData().addElement(tableElement);

//@@end

Write the following code in getTableDataVariant() method

public java.lang.String getTableDataVariant(IPrivateTableSelectView.ITableDataElement element)

//@@begin getTableDataVariant(IPrivateTableSelectView.ITableDataElement)

return element.index()==element.node().getLeadSelection()?"variant1":"";

//@@end

Deploy and Run Webdynpro Application.

Table Cell Popin in Ce 7.1 with an Example.

view

Unknown macro: {gliffy}

Popins are insertions between the rows of aTable, which may refer to a row or individual cells. TablePopinToggleCell
UI is used for expanding and collapsing the Table Cell Popin.For more information about theTableCellPopin, please
refer this link:
http://help.sap.com/saphelp_nw70/helpdata/EN/23/5e9041d3c72e7be10000000a1550b0/frameset.htm

Worked Example :
 Create a web dynpro Project and name it as "tablepopin".Create a Application - "TablePopApp" and Component

-"TablePopComp".
 Open the Component Controller .and Switch to the context Tab .Create a Context Node say TableNode and under
this node create the Following Attributes.

Context Attribute Type Calculated


Attribute

color String No

garments String No

price Decimal No

quantity Integer No

selectedCellVarian String No
t

selectedPopin String No

specialFeatures String No

textileCategory String No

totalPerQuantity Decimal Yes

Note: set the ReadOnly property of the totalPerQuantity as True.


 Copy the value Node from the Component Controller and Paste it in the View Controller Context.
 In the View layout, insert a Group to the RootElement and set the col count property to 3.To this group, add two Label
and TextView UI element.

 In the View Controller, Under the Value Node -TableNode, create a Calculated Attribute say "total" of type "Decimal"
and check the calculated Option. Set the readonly property of the total Attribute to true. Bind the text property of
OverAllTotalTextView to the TableNode Attribute -total.
 Set the Text property of the Group header as "Shopping Mart". set the text property of the CurrencyLabel to "USD
$"and TotalLabel to "Total".
 Insert a Scroll Container to the RootElement and insert a Table to it.Add four columns for to the Table
Namely:PopinTableColumn, GramentsTableColumn, PriceTableColumn and TotalTableColumn.Bind the dataSource
property of the Table to the ValueNode (TableNode).
 Insert a LinkToAction (Id is LinkToAction) and TablePopinToggleCell to the PopinTableColumn.
 Switch to the Action Tab of the View Controller and create a Action say ShowPopin with a Parameter say
NodeElement of type "ITableNodeElement".In the Action"ShowPopin" create a new Parameter say "NodeElement"
and Click on Browse.Go to the Java Native Type and type ITableNodeElement, click browse and finally select the
TableNodeElement belonging t

 o View.
 Bind the Action "ShowPopin" to the OnAction property of LinkToAction Ui Element. Right Click on the LinkToAction UI
Element and Select Parameter Mapping.In the Popup , drag and drop the NodeElement to the Action as shown
below.


 Set the variantKey property of the TablePopinToggleCell to a String say "CellVariant".

 This ToggleCell is the table cell variant which is for expanding and collapsing the Popin and the selectedCellVariant
of TableColumn and the variantKey of the ToggleCell should be bound to a common String Value . This Togglecell
shows an arrow down when the Popin is expanded and arrow Right when the Popin is collapsed.
 Insert a TextView and Header elements to other three Columns. Set the Text property of Header as "Garments". And
Bind the text Property of the TextView Ui element to the TableNode Value Attribute garments.

 In the Similar way set the text property of Header as "Price" and "Total" and Bind the text property of the TextView to
the TableNode Attributes (price and totalPerQuantity) for the PriceTableColumn and TotalTableColumn
correspondingly.

POPIN:

 Popin is controlled by the Application itself.For cell Popin , LinkToAction is used as TableCellEditor for Opening the
Popin.The content of the Popin can be a TextBar Ui Element or any other UI Element.The Context Attribute
"selectedPopin " decides which Popin Should be Shown .and This Attribute should be within the DataSource Property
of the Table and it Contains the ID of the TableColumn. if the selectedPopin does not have the id of the Table column
then no popin will be displayed.
 Right Click on the Table and Select Insert Popin.Let the Id of the Popin be "Popin". Right click on the Popin and insert
TextBar. And set the text property of the TextBar as "Enter the Quantity".
 In the Popin Content, insert a InputField and Transparent Container UI Element.Set the value property of the
InputField to the TableNode Attribute -quantity.Create a Action say "QuantityEntered" in the view Controller and bind
it to the OnEnter property of the InputField.

 To the Transparent Container, insert a Group say ProductdetailsGroup.Add four label and TextView to the Group
alternatively and bind the TableNode Attributes to the corresponding Label and TextView (Refer the Below Table).Set
the colCount property of the Group to 2.

UI Id Text Property of the UI Element.


Element

Label Garments "Garments"

TextView GarmentsTextView TableNode.garments

Label Color "Color"

TextView ColorTextView TableNode.color

Label SpecialFeatures "Special Features"

TextView SpecialFeaturesTextVie TableNode.specialFeatures


w

Label TextileCategory "Textile"

TextView TextileCategoryTextView TableNode.textileCategory


The Outline View of The TablePopCompView is :

Component Controller:

 The code mentioned below is used for populating the Table. We can also populate the data to the table from the
Backend.
 Add this code Begin Others:
 Add this code in the wdDoinit method:

 Add this code in the getTableNodeTotalPerQuantity_1 get method:

TablePopCompView --View Controller:


 Add this code in the wdDoModifyView Method:

 Add this code in the get method of the calculated Attribute Total_1:

 Add this code in the Action Method - ShowPopin:

 Now Save all the metadata, build the Project.Finally deploy and run the Application.The below figure shows the
expected Output.
Step 1

First a method has to be created in the view. The method is FILTER and it is associated with the event onFilter of
the UI Element MyFilterTable
Step 2

Create a context value attribute FILTER_USERNAME. This value attribute will be associated (bound) with the filter
value that you enter in the screen.

Step 3

Bind the context value attribute FILTER_USERNAME to the relevant column of the table. In this case it is bound with
Username.
Step 4

//@@begin onActionFilter(ServerEvent)//Step 1 -> Creating a link to the values present in cust


ay all results which start with 200

Output

Other Results

Display results where usernames contain only letters. In this case the filter criteria is [A-Z,a-z].*
Introduce a User and Role Based Access Into a Web Dynpro Project

1. Goal

This Wiki should help to introduce a role based access to your Web Dynpro application. You'll get all code snipets
that you'll need in your day-to-day work.

Of course there are other ways to do it. Nevertheless this introduction gives you a starting point.

2. Pre-Requisites

SAP NetWeaver: SAP NetWeaver 7.0 (2004s)

User: Already familiar with Web Dynpro. Already familiar on how to create users and roles in the SAP Web
Application Server.

3. Step-by-Step Solution

3.1 Create Users and Roles in SAP's Web Application Server

First you need to call the SAP Web Application Server to open the User Management console
Picture 1: Open the User Management console on your SAP Web Application Server

Now you need to login.


Picture 2: Login with the respective user (admin rights necessary)

To create a new user press the button "Create User".

Picture 3: Start creation of a new user

Type-in all user relevant data and press the "Save" button. Once you have created roles (see below) you can assign
those roles to the user by clicking on the tab "Assigned Roles".
Picture 4: Insert all user information

The user has been created.


Picture 5: The user has been created

To create a role switch the "Search Criteria" to "Role" and press the "Create Role" button.
Picture 6: Add a new role

Insert the relevant role data and click the "Save" button.

Picture 7: Save the role's data


The role has been created. The role is accessible through it's "Unique ID".

Picture 8: The role's unique ID

3.2 Bind library

To be able to access all relevant user information you need to bind a library to your project.

First right click on your project and select "Properties".

Picture 9: Properties of project

Now switch to the "Libraries" tab and click on "Add Variable".


Picture 10: Adding a variable to the libraries

Click on the "WD_RUNTIME" entry and press the "Extend..." button.


Picture 11: Extend build path

Scroll through the list until you find the extension "com.sap.security_2.0.0" entry. Expand it's folder select the library
com.sap.security.api.jar. After that press the "OK" button.

Picture 12: Add com.sap.security.api.jar

Finally you can save the newly added library by clicking on the "OK" button.
Picture 13: Save the changes

From this point on you can use the source code that is provided below.

3.3 Access the information

After the security library has been added to your project you can now use the following code snipets to access the
role based information. Should you get error messages after inserting it, don't forget to "Organize imports" (through
menu or simply with the keystrokes "Strg" + "Shift" + "O").

3.3.1 Get the name of the current user

public String getCurrentUserName() {

String result = null; IWDMessageManager manager = wdComponentAPI.getMessageManager();

try {

IWDClientUser user = WDClientUser.getCurrentUser();

IUser currentUser = WDClientUser.getCurrentUser().getSAPUser();

String userName = currentUser.getFirstName() + " " + currentUser.getLastName();

result = userName; }

catch (WDUMException ue) {

manager.reportException(ue.getMessage(), false);

return result;

3.3.2 Get the user-id of the current user

public String getCurrentUserId() {

String result = null; IWDMessageManager manager = wdComponentAPI.getMessageManager();

try {

IWDClientUser user = WDClientUser.getCurrentUser();

IUser currentUser = WDClientUser.getCurrentUser().getSAPUser();

String userId = currentUser.getUniqueName();

result = userId; }

catch (WDUMException ue) {

manager.reportException(ue.getMessage(), false);

return result;
}

3.3.3 Check if a user belongs to a role

The following function will check if a user belongs to a specific role:

public boolean userHasRole(String userId, String roleName) {

boolean result = false; IWDMessageManager manager = wdComponentAPI.getMessageManager();

try {

// get webdynpro user

IWDClientUser wdcu = WDClientUser.getCurrentUser();

// get sap WAS user for WD user

IUser sapUser = wdcu.getSAPUser();

// get role for name

IRole sapRole = UMFactory.getRoleFactory().getRole(roleName);

// check if user is member of role,

// the "true" attribute means, that role assignment might be

// indirect (ie. for a group in which user is a member

result = sapRole.isUserMember(sapUser.getUniqueID(), true);

// return a message in case of exception

catch (WDUMException e1) {

wdComponentAPI.getMessageManager().reportWarning("Error when obtaining user information : " +


e1.getMessage());

catch (UMException e2) {

wdComponentAPI.getMessageManager().reportWarning("Error when obtaining user information : " +


e2.getMessage());

// the result is true, if current user has the named role return result;

Email with Multiple Attachments to Multiple Recipients

view
This code snippet can be used to trigger email with multiple attachments to multiple receivers.
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

/**
* *********** Java Email with Multiple Attachments to Multiple Recipients *****************************************
* @author Mandeep Virk / Yogesh Varma (mandeep.virk@architectsap.com / yogesh.varma@architectsap.com)
* *****************************************************************************************************
*/

String hostName = "Put your Host Name";


String mailFrom = "Put Sender's Address";
String[] mailTo = "Put Multiple Recipient's Address";
String portNo = "Put Port Number";

Properties props = System.getProperties();


Session session = Session.getDefaultInstance(props,null);

try{

Message message = new MimeMessage(session);

message.setFrom(new InternetAddress(mailFrom));

message.setSubject("Put Your Text Here");

// Email to Multiple Recipients

InternetAddress[] mailToMultiple = new InternetAddress[mailTo.length];

for( int i=0; i<mailTo.length; i++ ){


mailToMultiple[i] = new InternetAddress(mailTo[i]);
}
message.setRecipients(Message.RecipientType.TO,mailToMultiple );

// For Multiple Attachments

MimeMultipart multipart = new MimeMultipart();


IWDResource resource = null;
String filePath = "Enter Your File Path Here";

for(int i=0; i<wdContext.node<NodeName>().size(); i++){


BodyPart attachment_bodypart = new MimeBodyPart();
if(wdContext.node<NodeName>().get<NodeName>ElementAt( i ).getResource() != null)
{ // Here getResource() is Value Attribute of Resource Type
resource = wdContext.node<NodeName>().get<NodeName>ElementAt( i ).getResource();
String fileName = resource.getResourceName();
if ((filePath != "") || (filePath != null))

Unknown macro: {if(new File(filePath).exists()){ File f = new File(filePath + fileName) ;


attachment_bodypart.setFileName( fileName ); attachment_bodypart.setDataHandler( new DataHandler( new
FileDataSource( filePath + fileName))); multipart.addBodyPart( attachment_bodypart ); }

} resource = null; } }

// Email body

BodyPart message_bodypart = new MimeBodyPart();


message_bodypart.setContent("Put Your Message Here", "text/html");
multipart.addBodyPart( message_bodypart); message.setContent( multipart);

// Transport Message

Transport transport = session.getTransport("smtp");


transport.connect( host,portNo,"Put Email Id for Authentication","Password");
transport.sendMessage( message, message.getAllRecipients()); transport.close(); }

catch (AddressException e) {

} catch (MessagingException e){

Getting Portal Host and PortNumber in WebDynpro Application.

getAbsoluteWebResourceURL() method of WDURLGenerator class which is used to get the Portal Host and Port
number is deprecated.

The alternative way to achieve this is to use IWDRequest.

IWDRequest req=WDProtocolAdapter.getProtocolAdapter().getRequestObject();
wdComponentAPI.getMessageManager().reportSuccess(req.getServerName());
wdComponentAPI.getMessageManager().reportSuccess(""+req.getServerPort());

How to create Portal User by using Web Dynpro Java

view
There are three way to create portal user

1. Through Visual Administrator

2. Through Portal

3. Through UserManagement API and Web Dynpro

In this wiki i will explain creating user by using UserManagement API and Web Dynpro

Steps

1. Create Web Dynpro Project Go to -> New -> Web Dynpro Project 2.Create One Application .Just righy click on
Application

3. Choose the radio button ''Create a new component'. Click on 'Next'.


4.Enter the Component Name, Window Name and View Name. You can change these names if you wish to. Click on
'Finish'.

Now fifth steps is very important

5. Right click on the Project Name and click on Properties

6. In the Properties window for the project choose 'Java Build Path -> 'Add External Jars'

7. Locate 'com.sap.security.api.jar' in the Eclipse plugins in your file system and click on 'Open'.

8.The same will be added to your Java Build Path. Click on 'OK'.

Then Create Context value attribute

FirstName ,LastName,Email,UserId

Click on <view name> -> Template -> Apply

Click on Form and then 'Next'.

Check all Check Boxes and click on 'Next'

Arrange the positions of your UI elements/ rename labels /edit them and click on 'Finish'.

The UI elements will be created.

Similarly, use the template 'ActionButton' to create a button.

Go to the action of the button 'onActionCreateUser()' and write the following code,

public void onActioncreateUser(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent )


{{color:#3f7f5f}//@@begin onActioncreateUser(ServerEvent)

try {

IUserFactory factory = UMFactory.getUserFactory();

IUserAccountFactory accountFactory = UMFactory.getUserAccountFactory();

String email = wdContext.currentContextElement().getEmail();

String fname = wdContext.currentContextElement().getFirstname();

String lname = wdContext.currentContextElement().getLastname();

String password = wdContext.currentContextElement().getPassword();

String userid = wdContext.currentContextElement().getUserid();

IUserMaint newUser = factory.newUser(userid);

newUser.setFirstName(fname);

newUser.setLastName(lname);

newUser.setEmail(email);

newUser.save();
newUser.commit();

IUserAccount account = accountFactory.newUserAccount(userid,newUser.getUid());

account.setPassword(password);

account.save();

account.commit();

wdComponentAPI.getMessageManager().reportSuccess("User Created..........."+userid);
}

catch (UMException e)

{{color:#3f7f5f}// TODO Auto-generated catch block

wdComponentAPI.getMessageManager().reportException(e.getMessage(),false);
e.printStackTrace();

}
//@@end{color}}Run the application and see the output.

Questions about WebDynpro

view
Q1:What is WebDynpro.
Ans: WebDynpro is the standard working model for building SAPNetweaver UserInterfaces

Q2:What are Main goals ofWebDynpro Or Why to use WebDynpro


Ans:
Support Platform independency
Support arbitrary Backends
Support reusability of components
Seperate Layout and Logic
Supports Stateful applications
Supports Dynamic programming and Synchronization

Q3: What are the Tools in Using WebDynpro


Ans: ViewDesigner
Model tools
Data modeler
Controller/Context Editor
NavigationModeler
MessageEditor
Explorer

Q4:How WebDynpro supports MVC


Ans:

Model-- > OPerations on Data


View--> UserInterfaces
Controller--> DataFlow

Q5:What is the Use and lifetime of a WebDynpro Component


Ans:
A Web Dynpro application defines a starting point for a
Web Dynpro component that the user can call in the Web browser

A Web Dynpro component's lifetime begins the first time it is called


at runtime, and ends with the lifetime of the Web Dynpro application
that called and thereby instantiated the component

Q6: What is WebDynpro Application


Ans:
A Web Dynpro application is an application that can be called from
the user interface. As an independent program unit it connects a URL
that can be accessed by the user with a window in the
Web Dynpro component.

An application is just a URL address for launching a Web Dynpro root component

When you run the application it navigate you to the initial view in the initial window.

Q7: WebDynpro Model?


Ans:
A Part(Central) Of WebDynpro That Makes Data Available
For The WebDynpro Application

The Web Dynpro tools support application development during the


implementation and design phases. When a Web Dynpro application
is developed, a platform-independent metamodel is created from which
Java classed are generated.

A model represents the data in the backend. Data might be from the R/3 system or web service

or other sources.

Q8: Ways to achieve Security in WebDynpro


Ans:
Regarding Security Aspect in WebDynpro Application,
The Following Categories Are Made

1: Authentication
2: Model Import Security
3: Front-End Security
4: Security Of URL Parameters
5: Security In SAP Enterprise Portal
6: StackTrace

Q9:What is the Difference between Action and Event


Ans:

Action:
Actions are runtime objects that can be enabled and disabled dynamically
Or
You can think of an action as the bridge that takes the event information raised by a UI
element in the client, reaches across the stateless HTTP layer and connects to the corresponding
event handler in the view controller
Event: Events are the triggers that cause the Web Dynpro runtime environment to respond to some sort
of user action

Q10: Difference between WebDynpro and Java


Ans:
WebDynpro is a UI FrameWork and
Java is a Programming Language

Q 11 What is a context

Ans:

A context represents the application metedate in hierarchical form

Each controller has a context, wheteher it is a view controller or component controller

A view context contain the data related to the view controls and the comopnents or custom context

keeps the data related to the component.

Q 12 Whwt is a component

Ans:

A component is a reusable UI program package

Q13.What is a component interface

Ans:

A component can copmmnicate with other one via component interface.

WebDynpro Java - UI -Development - Roadmap Element.

The Roadmap UI Element

I am trying to explain how to implement a Roadmap UI, which is a way to guid a user through a certain process.
(You know these cute little wizards...).

In our project the customer decided to let the user have a step-by-step experience when creating selection criteria for
selecting

Step 1: create adequate viewset


in our case we created a viewset consisting of 2 parts, one upper part to house the roadmap itself, and one lower part
to embed the views that should be shown with each step.

Step 2: place your RoadMap/RoadMapsteps.

in the layout part of the view, you first place a Roadmap UI Element, and inside of this you place the desired amount
of steps (remember the IDs of the steps, you will need them later...), or even better choose them wisely.

Step 2: create context for Roadmap, bind to the UI Element.

the currently selected step should be bound to the context so the view and UI Elment can remember it throughout the
process. We created in the View context a Value Node "DialogData", and in there a Value Attribute called
"selectedStep".

in the layout of the view select the RoadMap UI Element - right click it, and choose "Properties", you will then see the
properties of the selected UI Element on the right hand side, below the "WYSWIG" layout view.

in the Properties there will be one entry "selectedStep" (ElementProperties), bind it to the Context (DialogData-
selectedStep)

[you can see this in the picture of step 1: "selectedStep"]

Step 3: setup firstStep in navigation.


in contrast to our expecations, the Roadmap UI Element hasn't got a Property to define the first step in the Process,
you need to set the value of the "DialogData-selectedStep" Value Attribute (in our case in wdDoInit() of the Controller
- in your maybe case some more places...).

public void wdDoInit()

//@@begin wdDoInit()

wdContext.currentDialogkonfigurationElement().setSelectedStep(IPAVApplicationConstants.ROADMAP_SYSTEMSE
LECT);

//@@end

Step4: setup view for eventhandling.

in order to get the step the user has selected (by clicking on one of the steps), a parameter has to be passed to the
eventhandler that you provide later on, this (mapping-)definition is created in the wdDoModifyView(), but only the
firsttime it is
entered.

public static void

wdDoModifyView(IPrivateRoadmapIndicatorView wdThis,

IPrivateRoadmapIndicatorView.IContextNode wdContext,

com.sap.tc.webdynpro.progmodel.api.IWDView view, boolean firstTime) {

//@@begin wdDoModifyView

if (firstTime){

IWDRoadMap myRoadMap = (IWDRoadMap) view.getElement ("RoadMap");

myRoadMap.mappingOfOnSelect().addSourceMapping(IWDRoadMap.IWDOnSelect.STEP, // event parameter name

"step" // (type String)); }//@@end

in this way we declare that the event parameter defined by the Roadmap UI Element should be mapped to an Action
Parameter named "step".

Step5: create Action and Eventhandler for onSelect Event.

Back in the Layout view of the Roadmap we open up the properties of the Roadmap UI Element, this time to create
an Action, and an EventHandler to react on user Actions with the Roadmap UI Element. When creating the
EventHandler create a parameter named "step" (we mapped it earlier...)
Step6: implement the Eventhandler.

magically the step parameter is filled with the ID of the Roadmap Step selected by the user - which in turns can be
used to navigate to a different point in the process.

public void onActionRoadmapSelected(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent,


java.lang.String step )

//@@begin onActionRoadmapSelected(ServerEvent)

// take a look at wdDoModifyView for how to get to know where the parameter "step" comes from.

//DEBUG IWDMessageManager msgMgr = wdComponentAPI.getMessageManager();

//DEBUG msgMgr.reportSuccess("step:"+ step);


if ( step.equalsIgnoreCase(IConstants.ROADMAP_INSERT) ){

wdContext.currentDisplayElement().setSelectedStep(IConstants.ROADMAP_INSERT);

wdThis.wdFirePlugToSelectionCriteriaInputView();

} else ( step.equalsIgnoreCase(IPAVApplicationConstants.ROADMAP_UPDATE) ) {

wdContext.currentDisplayElement().setSelectedStep(IPAVApplicationConstants.ROADMAP_UPDATE);

wdThis.wdFirePlugToSelectionCriteriaUpdate();

Here we are the navigation works. The main issue was to get the value of the selected step, which is done in
wdDoModifyView() through addSourceMapping(...). Amazingly this is in deed documented in the Javadocs of
Webdynpro in
What’s a Mind Map?

Anyone who’s ever had to try and make sense of a large quantity of information will know that as soon as you try to
force that information into some sort of list or sequence, you often loose more than you gain. The list might look neat
and tidy, but you will not have an accurate representation of the inter-relationships between all the different facts.

The bottom line here is that information cannot be represented entirely sequentially or hierarchically. In reality, one
piece of information is related to multiple other pieces of information to form a web of relationships, associations and
dependencies.

A mind map is a simplified form of a diagram known as a Semantic Network. Mind maps have been used in many
different forms for many centuries, but have lately been popularized by the British psychologist and educationalist
Tony Buzan.

A mind map allows you to create a web of relationships between words, ideas and tasks. In creating this network or
web of relationships, you can communicate the structure of information in a way that is compact and easy to
understand. Rather than having to use several sentences of text to describe the relationship between a set of ideas,
you can simply place each idea on the page and draw lines between them. The lines can additionally be labelled in
order to add further description to the relationship. Typically, a mind map will start from a central topic, and from this
will spread out various related topics.

When used correctly, this diagramming technique can concisely describe the relationship between multiple ideas and
tasks yet require significantly fewer words than an equivalent plain text description would.

In addition to this, the associations between the information in a mind map act as veru effective triggers to memory,
and help you remember details about that particular topic that you thought you’d forgotten.

This is why a mind map has been chosen to represent the ideas, facts and tasks involved in understanding Web
Dynpro for Java.

Graphics and screen shots

The screen shots are taken from the Mindjet® MindManager® Viewer 7 running as a stand alone program as
opposed to a browser plug-in.

How to View the Mind Map


This mind map has been created using the Mindjet software called MindManager. In order to view this mind map, you
must install the Mindjet MindManager Viewer either as:

 A stand alone program


 As a browser plug-in (Only Internet Explorer v6.0 or higher)

Stand alone program installation

To install the Mindjet MindManager Viewer as a stand alone program, please follow the link to the Mindjet website
where the software is available for free download (25Mb download).

The viewer software is available in four different languages (English, German, French and Japanese) for both PC and
Mac systems.

Browser Plug-in

If you are using Internet Explorer version 6.0 or higher, then the plug-in will install automatically.

Depending on the security settings of your browser, you may see a security warning message displayed. Click on
"Yes" to install the ActiveX plug-in.

Figure 1: Possible security warning during plug-in installation

Follow this link to view the Web Dynpro for Java mind map using the browser plug-in.

Downloading the Mind Map

If you choose to install the stand alone Mindjet MindManager Viewer, then you need to have a local copy of the mind
map file. This is done by right-clicking on this link Web Dynpro mind map and select "Save Target As".
WARNING!
It is possible that the browser will mistake the mind map file for a ZIP file, and then try to open it with some tool such
as WinZIP or WinRAR. If this happens, you must make sure that the file extension is not changed to .zip. The mind
map file must have an extension of .mmap and must not be unzipped.

Using the Web Dynpro Mind Map

General Information

Once you have installed the Mindjet MindManager Viewer as either the stand alone program or the browser plug-in,
you will then be able to view and navigate around the Web Dynpro mind map.

Figure 2: The Default View for the Web Dynpro Mind Map

As you can see from Figure 2, radiating out from the central subject are nine different topics. Each one of these topics
is then broken down into further sub-topics. As these branches are expanded, further relationships will emerge
between the different sup-topic areas.

You will also notice from the diagram above that some of the links have icons to the right of the text. This indicates
that a hypertext link is available to take you to a document, presentation or web page within either SDN, or the Online
SAP Help or some other relevant information source.
Figure 3: When the same concepts appear in multiple locations within the mind map, blue association arrows link
them together.

Since facts cannot be arranged sequentially without significant degradation of the information content, you will see
the same concepts or topics appearing in multiple places across the map. When they do, you will see a blue
association arrow that connects them together. See Figure 3 above.

Mind map navigation

Once you have expanded several branches of the mind map, you will find that it rapidly becomes larger than the
available screen size. In this situation, you can either change the zoom level (Ctrl + spin mouse wheel) or drag the
whole map around to examine a particular area.

Dragging the map can be done by first left-clicking and holding, and then the mouse pointer changes to a hand and
you are then able to drag the whole map in any direction.

Be careful about expanding too many branches of this map at once! This map can grow to become very large and
you will not be able to see all the branches at once. It is recommended that you expand only the particular branch you
are interested in.
Figure 4: Since the mind map is very large, you should only expand the branches you are interested in.

Printing the mind map

It is quite possible to print the fully expanded Web Dynpro mind map - as long as you have a printer with paper
sufficiently large! For instance, the entire map can be printed successfully on an HP 1055CM printer. The resulting
print is about 1 metre wide and 2.5 metres high.

A word of warning about the print settings though! In the Page Setup menu, always ensure that the "Print
Background" option is switched off!

The reason is that the mind map has an off-white background colour defined for it. This makes it easier to read on the
screen, but if you attempt to print the fully expanded mind map, it will generate a print job of around 475Mb
(depending on the type of printer being used). Not surprisingly, a print job this size caused the above printer to abort
the job.

The answer is simply to switch off the background colour during printing, and the size of the print job drops to just
over 2Mb!
Figure 5: If you wish to print the fully expanded mind map, then ensure that the Background colour is not printed.

Export to Excel (Without third party APIs)

Applies to:
Webdynpro for Java.

Summary
This article explains in writing a generic method to export the contents of Webdynpro tables to Excel.

Author(s):
Company: Bristlecone
Created on: 11 Sep, 09
Author(s) Bio
N.Venkatraman working for Bristlecone India Ltd., as a Webdynrpo for Java develope.

Introduction
We use the Webdynpro tables in almost all the applications which we develop. We can provide the users to
download the data available in the table in the form of excel sheet, without much coding and trouble. This article
explains on how the data can be exported to excel, without using any third party APIs.

Pre - Requisite
1. Knowledge on Webdynpro for Java
2. Worked with Webdynpro Tables
3. Knowledge on basic HTML tags
Design & Code
As mentioned, we are going to export the table contents to excel without using any third party APIs. We will be
using the basic File IO concepts and basic HTML tags.
1. Add the following method in your webdynpro application
2. Invoke this method by passing the context node of the table
3. The method returns the name of the xls file created
4. Use the file name and create a WDResource for adding to Download UI Element
ExportToExcel Method:
public java.lang.String exportToExcel( com.sap.tc.webdynpro.progmodel.api.IWDNode node )

//@@begin exportToExcel()

try{

FileOutputStream fos=new FileOutputStream("Test.xls");

PrintStream ps=new PrintStream(fos);

ps.println("<html><body><table border=1>");

Iterator attributes=node.getNodeInfo().iterateAttributes();

ps.println("<tr>");

while(attributes.hasNext()){

ps.println("<th>");

DataAttributeInfo attrName=(DataAttributeInfo)attributes.next();

ps.println(attrName.getName());

ps.println("</th>");

ps.println("</tr>");

for(int i=0; i < node.size();i++){

attributes=node.getNodeInfo().iterateAttributes();

ps.println("<tr>");

IWDNodeElement ele=node.getElementAt(i);

while(attributes.hasNext()){

ps.println("<td>");

DataAttributeInfo attrName=(DataAttributeInfo)attributes.next();

ps.println(""+ele.getAttributeAsText(attrName.getName()));

ps.println("</td>");

ps.println("</tr>");

ps.println("</table></body></html>");

ps.flush();
ps.close();

fos.close();

catch(Exception e){

wdComponentAPI.getMessageManager().reportException(e.getMessage(), false);

finally{

return "Test.xls";

} }

You might also like