This tutorial is for the DynPagePlus framework version 1.0.
This tutorial is part of the DynPagePlus framework which is licensed under LGPL license
Setting up the environment
It's assumed that you'll be using SAP NetWeaver Developer Studio as your IDE and that you already have some experience with the Enterprise Portal perspective.
Only prerequisites for this tutorial is that you have installed SAP NetWeaver Developer Studio, a JDK of 1.4.2 and have access to a portal for deployment/testing.
Creating the project
If not already started, start your developer studio. Switch to the enterprise portal perspective. Click File -> new -> project choose portal application and create portal application.

Click next and write "DynPagePlus_tutorial" as the name of you portal application. Click finish. Now you're ready to start the tutorial.
DynPagePlus tutorial
The reason for starting the tutorial at this point is that you can use the steps here as a checklist when implementing a new portal component in an existing application.
Creating the portal component
The easiest way to create a DynPagePlus portal component is to create an ordinary DynPage and convert it to a DynPagePlus. To create the DynPage do the following:
Click: File -> New -> Other and choose Portal Application and Create a new Portal Application object.
Click next and choose the "DynPagePlus_tutorial" project and click next again.
Expand the Portal Component and select DynPage and click next.
Fill in the form as the image illustrates.

Click finish and you'll have an DynPage generated and description snip in the portalapp.xml.
Adding the library
In order to use the DynPagePlus framework, you'll need to import the jar file in to the project. There are two places you could put it, the first is in the PORTAL-INF/lib and the second is in the PORTAL-INF/private/lib the latter is the correct choice. To import the jar file to your portal application you can choose the import feature of Developer Studio:
In the Package Explorer navigate to DynPagePlus_tutorial/dist/PORTAL-INF/private/lib and click File -> Import and select File system

Click next.
Click Browse and select the path to the folder where you have previously downloaded the DynPagePlus library, mine is C:\Work\libs\DynPagePlus.
Check the square next to DynPagePlus-1.0.jar and click finish.
In the Package Explorer right click the DynPagePlus_tutorial project and choose Properties from the context menu. Navigate to Java Build Path and choose the Libraries tap.

Click Add jars and navigate to the DynPagePlus jar file and select it and click OK

Click OK in the properties dialog as well. Now your project is ready to use the DynPagePlus framework.
Converting the DynPage
The next step is optional but recommended.
Converting the nested class to top level
If not already open, open the HelloPortal.java file. Double click the class name for the nested static class HelloPortalDynPage to select it and right click the selected class name and choose Refactor -> Convert nested type to top level..

Click OK in the following dialog
The result is that the HelloPortalDynPage is extracted from the HelloPortal.java file and is inserted in a new file called HelloPortalDynPage.java in the same package. The HelloPortal.java class you will not need to modify ever again.
Converting the DynPage to DynPagePlus
Open the HelloPortalDynPage.java file. Make the class extend DynPagePlus instead of DynPage. Add the following import statement to the file to get rid of the red lines:
import net.sf.dynpageplus.DynPagePlus;
Remove the methods doInitialization, doProcessBeforOutput and doProcessAfterInput as these method are automated by the DynPagePlus framework.
Hit <ctrl> + <shift> + O (organize imports) to remove the obsolete import statements. You class should look something like this now:
package net.sf.dynpageplus.tutorial; import net.sf.dynpageplus.DynPagePlus; public class HelloPortalDynPage extends DynPagePlus { }
This is the minimalistic DynPagePlus implementation, this will compile but it will not show anything when run.
Adding your first face
Like the user guide says, we like to preserve the idea about splitting op what is controller and what is view from the JspDynPage components. In DynPagePlus this is done with faces. A responsibility of a face is equal to that of a JSP. It holds the GUI definition for one page of the portal component.
In order to implement a face you create a class that extends net.sf.dynpageplus.Face. The HtmlbDynPage forces you to implement a method called buildUI which is used to create the GUI and map properties to components. Lets do so now.
Navigate to the package net.sf.dunpageplus.tutorial, right click and select New -> Other from the context menu.

Select Java and Class and click next. Fill out the dialog as shown on the next screenshot.

Make shure to check the bottom checkbox. Click finish. Now you should have a class who looks something like this:
package net.sf.dynpageplus.tutorial; import net.sf.dynpageplus.Face; import com.sapportals.htmlb.Form; public class InitialFace extends Face { /* (non-Javadoc) * @see net.sf.dynpageplus.HtmlbDynPage#buildUI(com.sapportals.htmlb.Form) */ public void buildUI(Form arg0) { // TODO Auto-generated method stub } }
In order to implement the GUI of our example, change the code InitialFace class to th following:
package net.sf.dynpageplus.tutorial; import net.sf.dynpageplus.Face; import com.sapportals.htmlb.Form; public class InitialFace extends Face { /* (non-Javadoc) * @see net.sf.dynpageplus.HtmlbDynPage#buildUI(com.sapportals.htmlb.Form) */ public void buildUI(Form form) { form.addComponent(getLabel("Hello Portal")); } }
This obviously adds a label with the text "Hello Portal" to the form. The getLabel method is a convenience method for instantiating a label and setting the text of the label in one line. The HtmlbDynPage class holds a lot of these methods.
The next thing we have to do is to let our DynPagePlus know about the face. This is done by adding them to the DynPagePlus implementation. The place to that is The method doInit, whitch by the way is guaranteed to only get run once, namely when the DynPagePlus is being initialized.
Open the HelloPortalDynPage.java file an add the following code to the class:
protected void doInit() { addFace(DEFAULT_FACE, InitialFace.class); }
The DEFAULT_FACE is the one being displayed when none other is selected. The reason for adding the class definition in stead of the instance is that the DynPagePlus framework responsible for instantiating and initializing the class as well as calling their buildUI method. Also, because a face usually instantiates a lot of sub objects, they're very expensive to instantiate, so the instantiation is first done right before they are used to insure no faces is instantiated without reason.
Now is a good time to build, deploy and run your component. The result should something like the screenshot below:

When looking back on what you just have accomplished, you should notice one thing, you didn't write any more code than exactly what you needed to get the job done. In this case this was only two lines real code.
This is of course not a very usable application but it illustrates the simplicity goal of the DynPagePlus framework. Now lets do something with a little interaction from the user.
Adding interaction
We can still use the InitialFace class we just created for our next task, so lets do so.
We'll need to create a initial face which asks the user for his or hers name. And the when the clicks a button we greet the user and use the name in the greeting. (seen it before?? nah rubbish.)
Change the code of the initialFace class to this:
package net.sf.dynpageplus.tutorial; import net.sf.dynpageplus.Face; import com.sapportals.htmlb.Button; import com.sapportals.htmlb.Form; import com.sapportals.htmlb.GridLayout; import com.sapportals.htmlb.GridLayoutCell; import com.sapportals.htmlb.InputField; import com.sapportals.htmlb.Label; public class InitialFace extends Face { public void buildUI(Form form) { // Create a lyout manager and add it to the form. GridLayout layout = new GridLayout(); form.addComponent(layout); // create a label and add it to the layout Label nameLabel = getLabel("What is your name dear user?"); layout.addCell(1, 1, new GridLayoutCell(nameLabel)); // create en input field and add it to the layout InputField nameField = new InputField("nameField"); // The string given to the InputFIeld constructor is the ID of the // component. This is important later as we use it later! layout.addCell(1, 2, new GridLayoutCell(nameField)); // Create a button to click on when filed out your name, and add it to the layout Button nextButton = new Button("nextButton"); nextButton.setText("Next"); nextButton.setOnClick("greetUser"); layout.addCell(2, 2, new GridLayoutCell(nextButton)); } }
As the line "nextButton.setOnClick("greetUser");" indicates, we'll need to make a event method called onGreetUser in the DynPagePlus exactly as if it were an ordinary DynPage. We'll get back to that later, but first we should create a new face for the greeting.
Create a class like you did before with InitialFace.java but call this class for GreetingFace(.java).
Write the following code:
package net.sf.dynpageplus.tutorial; import com.sapportals.htmlb.Form; import com.sapportals.htmlb.TextView; import net.sf.dynpageplus.DefaultDataBean; import net.sf.dynpageplus.Face; public class GreetingFace extends Face { public void buildUI(Form form) { // Since we haven't registered a data bean, a default one based on a map // is provided for us. DefaultDataBean db = (DefaultDataBean) dataBean; // Create the message String msg = "Hello " + db.getString("nameField") + " I hope you'll have a nice day"; // Create the TextView for displaying the message TextView greeting = getTextView(msg); // And finally adding the TexView to the form form.addComponent(greeting); } }
As you can see from the code, a default data bean is provide since we didn't register one. In the most MVC frameworks you'll some kind of Java bean to transport data between the view and the controller and between the controller and the model. This data bean usually holds no logic but only data hence the name data bean. The DynPagePlus framework uses the same approach, but here a default data bean is provided which handles the data in a java.util.Map.
Another way of doing this is to register a data bean with the DynPagePlus. You can use the method registerDatabean method and the bean to register could be any object. The data mapping is handeld via a naming convention stating that if you have a mappable component with the ID “test†you should have a property named “testValue†and testValue should have a public setter method. For instance if we were to implement a custom data bean i our little application here it should have a property named nameFieldValue and a public setter for that value called setNameFieldValue and the type of the nameFieldValue should be String.
Anyway see a lot more about this in the javadocs and on the site http://dynpageplus.tbbe.dk.
Back to the GreetingFace class. The next thing is that the message is created, the TextView is created using one of the convenience methods and finally the TextView is added to the form.
Before we create the event method we have to add a state for the new face as well. Add the following constant to the HelloPortalDynPage:
public static final int GREET_FACE = 2;
The reason for this is that it's much more readable than addState(2, Gree.... Next add the following line to the doInit method of HelloPortalDynPage:
addFace(GREET_FACE, GreetingFace.class);
This tells the DynPagePlus framework that it has to manage state for the GreetingFace class as well. Now we can implement the event method. Add the following method to the HelloPortalDynPage:
public void onGreetUser(com.sapportals.htmlb.event.Event event) { setState(GREET_STATE); }
Since we do not process any data we only need to tell the DynPagePlus framework that we'll like the GreetingFace to be displayed now.
Now is a good time to build, deploy and run our little example. The result should look like this:


Lets look back on what we have done. We now have to faces (views) and one DynPagePlus instance (controller).
As you can see only the code for controlling the flow of the application is in the controller and the display logic all in the views where it should be. So what we have accomplished is that we have preserved a highly clean Model-View-Control pattern and automated all the tedious stuff away, thats pretty neat.
DynPagePlus and Internationalization (I18N)
The DynPagePlus framework is helping you with the I18N stuff by providing the resource bundles in the faces as well as in the DynPagePlus instances. But in order for this to work you have to create the property files and you have to add the ResourceBundleName to the description in portalapp.xml for your portal component.
Adding internationalization
If we were to internationalize our application from before we would first have to create the property file for storing the texts. This is done this way:
Navigate to the package net.sf.dynpageplus.tutorial and right click on it and choose New -> Other.
Choose Simple and File and click next. Write HelloPortal.properties in the Filename field.

Click finish.
Add the following lines to the property file:
initialFace.hellotext=What is your name dear user? initialFace.nextbutton.label=Next
Save and close it.
Add the resource bundle to the portalapp.xml file.
Open the projects portalapp.xml file and click on the HelloPortal link in the components section. This brings you to the details of the component specification.
Right click on the component-config element ad select Add component-config property from the context menu. Select Add standard from the component-config dialog. Select ResourceBundleName from the dropdown list new dialog and click Ok.

Write "net.sf.dynpageplus.tutorial.HelloPortal" as the value of the property.

Click Ok, Finish and save the portalapp.xml.
What we need to do now is to add the texts to the components in the InitilFace. Change the line of code where add the label from
Label nameLabel = getLabel("What is your name dear user?");
To
Label nameLabel = getLabel(getLocalizedText("initialFace.hellotext"));
And the line where we set the test of the button from
nextButton.setText("Next");
To
nextButton.setText(getLocalizedText("initialFace.nextbutton.label"));
Remember to only provide the default language for your application, if others are needed you can always use the Translation Workbench of the portal to add translations.
Warning: If you're seeing the keys of the property file in stead of the values you might have to tell Developer Studio to include resources other than Java sources in the jar files. To do that navigate to Window -> Prefrences. Expand SAP Enterprise Portal and select Application Development Studio. Make shure the checkbox "Yes, I want non Java sources included into the portal component jars" is checked.
Feedback
If you have tried this tutorial any comments is of great value for us. You can simply send them in an email to tbbe@users.sourceforge.net.
We of course hope you will benefit from this tutorial and the framework in general.