Accueil > Eclipse RAP > My first steps with Eclipse RAP [step5]

My first steps with Eclipse RAP [step5]


In [step4], we have explained how OSGi container and Servlet container can work together. In this article we will explain the generated code of the RAP Hello World that we have generated in the [step1]..

Eclipse RAP Home Page describes RAP like this :

RAP is very similar to Eclipse RCP, but it has an alternative implementation of the SWT API (called RWT) which renders the widgets remotely in a web browser. The RAP application runs on a servlet container and clients can access the application with standard web browsers.

This schema shows RAP architecture. I will use this schema in my articles to explain step by step each component of the RAP architecture. RAP application (like RCP Application) is an Eclipse Plug-In based on the Workbench component. In this article we will see RAP Application and Workbench components :

  • the Workbench component is a collection of windows. Each window contains a menu bar, a toolbar, a shortcut bar and one or more perspectives. Please read Inside the Workbench for more information. For RAP Application, Workbench is managed with the org.eclipse.rap.ui.workbench bundle.
  • RAP Application is an Eclipse Plug-In based on the Workbench. It’s our org.akrogen.dynaresume.raphelloworld bundle.

I suggest you to read Rich Ajax Platform, Part 1: An introduction which explains the generated RAP application (like explained in this article) and compare it with RCP Application code.

RAP project org.akrogen.dynaresume.raphelloworld

Here is a screen of the workspace of the generated RAP project org.akrogen.dynaresume.raphelloworld :

A RAP application is an Eclipse Plug-In which contains :

RAP applictation is like RCP Application : an OSGi bundle which describes its dependencies, its identifiant… into the MANIFEST.MF file. Other informations like UI (Menu, Perspective, View…), are declared in a plugin.xml file.

OSGi dependencies

As we have seen in the [step3], OSGi manage dependencies (Plug-In Dependencies) with Required-Bundle and Import-Package. If you see the RAP Application you can notice this project depends on several JAR (Plug-In Dependencies). Open the MANIFEST.MF and go to the MANIFEST.MF tab :

In this schema you can see the link between Plug-In Dependencies JARs and MANIFEST.MF which declares Required-Bundle and Import-Package. Those 2 OSGi meta-data are used to set the needed dependencies for our RAP Application. You can manage with PDE those dependencies if you go to the Dependencies tab :

Required-Bundle

Any RAP Application is based on the org.eclipse.rap.ui Plug-In :

Require-Bundle: org.eclipse.rap.ui

If you double click on the org.eclipse.rap.ui item of the Dependencies list, it opens the MANIFEST.MF of the org.eclipse.rap.ui Plugin-In :

Bundle-SymbolicName: org.eclipse.rap.ui; singleton:=true
...
Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.6.0,4.0.0)
 ",org.eclipse.rap.rwt;bundle-version="[1.3.0,2.0.0)";visibility:=reex
 port,org.eclipse.rap.jface;bundle-version="[1.3.0,2.0.0)";visibility:
 =reexport,org.eclipse.rap.ui.workbench;bundle-version="[1.3.0,2.0.0)"
 ;visibility:=reexport,org.eclipse.core.expressions;bundle-version="[3
 .4.0,4.0.0)",org.eclipse.osgi.services;bundle-version="[3.2.0,4.0.0)"
...

You can notice that there are other dependencies, like org.eclipse.rap.rwt that you can see as JAR in the Plugin Dependencies of our project.

Import-Package

RAP Application is a WEB Application. It needs to have javax.servlet.* dependencies which is managed with Import-Package :

Import-Package: javax.servlet;version="2.4.0",
 javax.servlet.http;version="2.4.0"

MANIFEST.MF

Here is the content of the META-INF/MANIFEST.MF file generated :

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: RAP Hello World
Bundle-SymbolicName: org.akrogen.dynaresume.raphelloworld; singleton:=true
Bundle-Version: 1.0.0.qualifier
Require-Bundle: org.eclipse.rap.ui
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: javax.servlet;version="2.4.0",
 javax.servlet.http;version="2.4.0"

This META-INF.MF file is a part of an OSGi bundle. So RAP Application (like RCP Application) is an OSGi bundle. Interesting OSGi meta-datas in the MANIFEST.MF are :

  • Bundle-SymbolicName declared the option singleton:=true :
    Bundle-SymbolicName: org.akrogen.dynaresume.raphelloworld; singleton:=true
    

    This means that RAP Application is a singleton, in other words it’s not possible to have several versions in the OSGi container several versions of the same RAP Application. The singleton=true is declared because it’s possible to extend the RAP Application with extension point mechanism (declared in the plugin.xml) with other plugins to add for instance Menu (like when you develop Plug-In for IDE Eclipse). Plugins which extend the RAP Application are applied for a given RAP Application. (It’s the same thing for RCP Application).

  • Require-Bundle is declared like this :
    Require-Bundle: org.eclipse.rap.ui

    This declaration means that RAP Application depends on the required org.eclipse.rap.ui bundle.

  • Import-Package is declared like this :
    Import-Package: javax.servlet;version="2.4.0",
     javax.servlet.http;version="2.4.0"

Java classes

A RAP Application (like RCP Application) must define 2 components :

  • the entry point of the application which instantiate the workbench. This is done with the class org.akrogen.dynaresume.raphelloworld.Application which implements the org.eclipse.rwt.lifecycle.IEntryPoint interface. The IEntryPoint#createUI() method must be implemented to create the workbench. For RCP Application, this entry point is done with a class which implements org.eclipse.equinox.app.IApplication
  • the default perspective used by the created workbench. PDE generates org.akrogen.dynaresume.raphelloworld.Perspective which is a Perspective factory which implements org.eclipse.ui.IPerspectiveFactory. In the Perspective you can for instance add a View to add UI content.

We will see how this 2 concepts work together in the following article.

Application

Here is the code of the generated org.akrogen.dynaresume.raphelloworld.Application class :

package org.akrogen.dynaresume.raphelloworld;

import org.eclipse.rwt.lifecycle.IEntryPoint;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.application.WorkbenchAdvisor;

/**
 * This class controls all aspects of the application's execution
 * and is contributed through the plugin.xml.
 */
public class Application implements IEntryPoint {

	public int createUI() {
		Display display = PlatformUI.createDisplay();
		WorkbenchAdvisor advisor = new ApplicationWorkbenchAdvisor();
		return PlatformUI.createAndRunWorkbench( display, advisor );
	}
}

The code

PlatformUI.createAndRunWorkbench(display, advisor);

creates an instance of the workbench by providing an instance of the generated org.akrogen.dynaresume.raphelloworld.ApplicationWorkbenchAdvisor class which extends the org.eclipse.ui.application.WorkbenchAdvisor class. ApplicationWorkbenchAdvisor is used to set the default perspective ID to use for the workbench.

This entry point is declared in the plugin.xml like this :

<extension
       point="org.eclipse.rap.ui.entrypoint">
   <entrypoint
         class="org.akrogen.dynaresume.raphelloworld.Application"
         parameter="hello"
         id="org.akrogen.dynaresume.raphelloworld.Application">
   </entrypoint>
</extension>

The parameter hello is used to define the entry point ID of our RAP Hello World. This entry point ID is used in the http://127.0.0.1:8080/rap?startup=hello URL with the startup parameter. In our case, hello is the the entry point ID of our RAP Application.

ApplicationWorkbenchAdvisor

Here is the code of the generated org.akrogen.dynaresume.raphelloworld.ApplicationWorkbenchAdvisor class :

package org.akrogen.dynaresume.raphelloworld;

import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchAdvisor;
import org.eclipse.ui.application.WorkbenchWindowAdvisor;

/**
 * This workbench advisor creates the window advisor, and specifies
 * the perspective id for the initial window.
 */
public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {

	private static final String PERSPECTIVE_ID = "org.akrogen.dynaresume.raphelloworld.perspective";

    public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
        return new ApplicationWorkbenchWindowAdvisor(configurer);
    }

	public String getInitialWindowPerspectiveId() {
		return PERSPECTIVE_ID;
	}
}

This class extends the org.eclipse.ui.application.WorkbenchAdvisor class which sets several informations for the created workbench :

  • perspective ID to use by default by implementing the WorkbenchAdvisor#getInitialWindowPerspectiveId() method.
    In our case, this perspective ID is org.akrogen.dynaresume.raphelloworld.perspective. This ID is used to retrieve the right perspective
    which is declared in the plugin.xml file :

    <perspective
                name="Perspective"
                class="org.akrogen.dynaresume.raphelloworld.Perspective"
                id="org.akrogen.dynaresume.raphelloworld.perspective">
    </perspective>

    This declaration means that org.akrogen.dynaresume.raphelloworld.Perspective class will be used as Perspective.

  • the configuration to use for the (globale) window of the workbench (like menus, window title…) is done by extending the WorkbenchAdvisor#createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) method.
    In our case, this is done with the generated org.akrogen.dynaresume.raphelloworld.ApplicationWorkbenchWindowAdvisor class.

ApplicationWorkbenchWindowAdvisor

Here is the code of the generated org.akrogen.dynaresume.raphelloworld.ApplicationWorkbenchWindowAdvisor class :

package org.akrogen.dynaresume.raphelloworld;

import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;
import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchWindowAdvisor;

/**
 * Configures the initial size and appearance of a workbench window.
 */
public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {

    public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
        super(configurer);
    }

    public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) {
        return new ApplicationActionBarAdvisor(configurer);
    }
    
    public void preWindowOpen() {
        IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
        configurer.setInitialSize(new Point(400, 300));
        configurer.setShowCoolBar(false);
        configurer.setShowStatusLine(false);
        configurer.setTitle("Hello RAP");
    }
}

This class extends org.eclipse.ui.application.WorkbenchWindowAdvisor and is used to configure the workbench window like :

  • window size, title… which is done in the ApplicationWorkbenchWindowAdvisor#preWindowOpen() method :
    public void preWindowOpen() {
    	IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
    	configurer.setInitialSize(new Point(400, 300));
    	configurer.setShowCoolBar(false);
    	configurer.setShowStatusLine(false);
    	configurer.setTitle("Hello RAP");
    }
  • menu bar of the window which is done in the ApplicationWorkbenchWindowAdvisor#createActionBarAdvisor(IActionBarConfigurer configurer) method which must return an instance of org.eclipse.ui.application.ActionBarAdvisor :
    public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) {
    	return new ApplicationActionBarAdvisor(configurer);
    }

    In our case menu bar of our RAP application is managed with org.akrogen.dynaresume.raphelloworld.ApplicationActionBarAdvisor class, which is empty. This is done with the org.akrogen.dynaresume.raphelloworld.ApplicationActionBarAdvisor

ApplicationActionBarAdvisor

Here is the code of the generated org.akrogen.dynaresume.raphelloworld.ApplicationActionBarAdvisor class :

package org.akrogen.dynaresume.raphelloworld;

import org.eclipse.jface.action.IMenuManager;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;

/**
 * Creates, adds and disposes actions for the menus and action bars of
 * each workbench window.
 */
public class ApplicationActionBarAdvisor extends ActionBarAdvisor {

    public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) {
        super(configurer);
    }

    protected void makeActions(IWorkbenchWindow window) {
    }

    protected void fillMenuBar(IMenuManager menuBar) {
    }
    
}

In our case, this class does nothing. We will see in the next articles how to implement this class to have menu.

Perspective

Here is the code of the generated org.akrogen.dynaresume.raphelloworld.Perspective class :

package org.akrogen.dynaresume.raphelloworld;

import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPerspectiveFactory;

/**
 * Configures the perspective layout. This class is contributed 
 * through the plugin.xml.
 */
public class Perspective implements IPerspectiveFactory {

	public void createInitialLayout(IPageLayout layout) {
	}
}

For the moment the Perspective is empty. We will see in the next article how to add a View to add UI content.

plugin.xml

Here is the content of the generated plugin.xml file :

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>

   <extension
         point="org.eclipse.rap.ui.entrypoint">
      <entrypoint
            class="org.akrogen.dynaresume.raphelloworld.Application"
            parameter="hello"
            id="org.akrogen.dynaresume.raphelloworld.Application">
      </entrypoint>
   </extension>
   <extension
         point="org.eclipse.ui.perspectives">
      <perspective
            name="RAP Perspective"
            class="org.akrogen.dynaresume.raphelloworld.Perspective"
            id="org.akrogen.dynaresume.raphelloworld.perspective">
      </perspective>
   </extension>

</plugin>

This XML file declares the 2 required components (called extension point) for RAP Application :

  • the Application class is used to create the workbench.
  • the default Perspective class is used for the default perspective of the workbench.

Extension Point are the way for Eclipse RCP, Eclipse IDE, Eclipse RAP to extend the Workbench UI or for many things. You can create your own Extension Point to give the possibility to extend your Application for another contributor (Plugin System).

Conclusion

RAP Hello World is a good sample code to explain the required Java classes and extension points (plugin.xml) to declare to have an empty RAP Application. As you can see, the required RAP Application code is very light (few classes to create, few extension point to declare). This RAP Application code is the same (except for the IEntryPoint) than RCP Application (we will see that in the next articles) and provides the capability to benefit from Single Sourcing for having RCP (Fat application) and RAP (WEB Application) Application with the same code. In this article we have explained the Workbench and RAP Application components described in the RAP schema.

In the next article [step6] we will improve our RAP Application by adding a View to the perspective with RWT Text and Label widgets. RWT is an implementation of SWT which manage Javascript (Qooxdoo). We will see how it’s easy to add UI widgets without coding Javascript or HTML. RWT (Java SWT implementation) will be used to do that.

Catégories :Eclipse RAP
  1. mai 24, 2011 à 10:40

    I don’t think you need IEntryPoint anymore… and you can just use IApplication… this is supported since 1.3…

    http://www.eclipse.org/rap/noteworthy/1.3/news_M5.php

    • mai 25, 2011 à 5:53

      Hi Chris,

      Thank a lot for this information! I will test with IApplication (for Single Sourcing, it’s very cool to have this feature). IMHO I think RAP Tooling should generate IApplication instead of IEntryPoint.

      Regards Angelo

  1. mai 24, 2011 à 9:45
  2. mai 31, 2011 à 1:52
  3. août 8, 2011 à 3:43

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :