Eclipse Yoxos Services Downloads Blogs About
Home > Blogs >

Posts Tagged ‘Single Sourcing’

on Jul 8th, 2011Single-Sourcing with declarative services

In my last blog post I introduced the idea of using OSGi services for single sourcing a RAP/RCP application. I think this approach is quite elegant, but it has one major drawback. When you use normal OSGi services in your application you will mix your application code with the OSGi Framework code everytime you reference or register a service. Not only does this look ugly, it’s also hard to test.

Luckily there is a lifesaver called Declarative Services. (For those of you who are familiar with declarative services, skip to the next paragraph.) The OSGi declarative services (ds) are specified in the OSGi compendium so they are standardized. It’s just a component framework on top of OSGi services. It gives you the ability to register and consume services in a declarative way using some xml files and simple accessors in your classes.

I’ll take the same example from in my last blog post and use it to look at ds for single sourcing.  In that blog, we single sourced a themed button widget.  We can use the same interfaces and service implementations, and the only differences will be how the services will be registered and referenced.

First, let’s take a look at the service registration. In our example we need to register the services in the rap and rcp bundles. It’s common practice to put all service declarations in a folder called OSGI-INF in the root of your project. Once you’ve created this folder you can create a “component definition” using the wizard. After this you need to fill in three things: first, the filename of your choice, second, the component name which needs to be unique in the framework and third, the component itself.

componentWizard Single Sourcing with declarative services

The component is the fully qualified classname of your implementation. In the case of service registration, it’s your service implementation. To add the service registration, press ‘Finish’ to open the component editor. We only want to register a service, so we jump to the service tab. In the bottom section you can add the service interface.

To understand what happens in the background let’s recap what we have declared. We defined a service interface, a service implementation, a component name and a filename. The component framework takes care of instantiating the service implementation and registering it as a service using the service interface. It registers the component using the component name. The filename will be automatically added to your bundle’s manifest. That’s all, the next time we start this bundle the service will be registered. Your component definition should look something like this:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="com.eclipsesource.app.rap.service.provider">
   <implementation class="com.eclipsesource.app.rap.RAPSingelSourcingService"/>
   <service>
      <provide interface="com.eclipsesource.app.ISingleSourcingService"/>
   </service>
</scr:component>

Now we get to the service referencing. As you recall, we need to reference the service in our app bundle. Therefore, we need to create a component in this bundle too. In this example I decided to reference the service in the bundle’s activator and provide it with a static accessor. But you can reference it wherever you want. In this case the component is our Activator. The only difference to the service registration is in the service tab of the component editor. Instead of providing a service, we are now referencing one. You can do this by clicking ‘Add’ in the upper section of this tab.

serviceReferencing Single Sourcing with declarative services

After this you need to declare the Interface of the service you want to reference, in our case the ISingleSoucingService. The question is now, “how does this service finds its way to the Activator?” The answer is binding methods. In the reference you can specify a bind and an unbind method e.g. setService and unsetService. You need to add these methods to your activator with the service as a parameter. That’s all – we are referencing the service now. Your component should look something like this:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" enabled="true" name="com.eclipsesource.app.servic.consumer">
   <implementation class="com.eclipsesource.internal.app.Activator" />
   <reference bind="setSingleSourcingService" cardinality="1..1" interface="com.eclipsesource.app.ISingleSourcingService" name="ISingleSourcingService" policy="dynamic" unbind="unsetSingleSourcingService"/>
</scr:component>

The last thing we need is a little bit of glue to bring these components together. The glue is in the org.eclipse.equinox.ds bundle. This bundle contains the component framework implementation, and to make everything work together you need to add this bundle to your launch configuration. It’s not included in the RAP target components, but you can download it using the Indigo release site or the Equinox SDK.

I added a branch called “ds” to the repository on github from the last blog. This branch represents an example implementation using ds for single sourcing.

Have fun declaring services icon wink Single Sourcing with declarative services

on Jun 23rd, 2011Uploading files with RAP 1.4

One of the new things in RAP 1.4 is the FileUpload widget in RWT, that replaces the old Upload widget from the sandbox. And there’s some more new upload stuff in the RAP Incubator. Here’s how to use the new features to upload files with RAP 1.4.

The FileUpload is a new widget that wraps the HTML file selection <input> tag. It looks like a button, and when it’s pressed, a native file dialog opens up that lets users select a file from their local file system. On file selection, a SelectionEvent will be fired. You can then programmatically upload the selected file to an http server using FileUpload.submit( URL ).

FileUpload Uploading files with RAP 1.4

In order to receive and store the uploaded files on the server, you also need a server-side component. We created such an upload server component in the RAP Incubator. It’s called FileUploadHandler and it uses the Apache fileupload component internally. It’s included in the bundle org.eclipse.rap.rwt.supplemental.fileupload. This handler accepts file uploads to a certain URL (FileUploadHandler.getUploadUrl()) and delegates the data to a FileUploadReceiver. You can either use the provided DiskFileUploadReceiver or create your own receiver to do whatever you like with the uploaded data: put it into a database, or simple analyze the data and discard it.

Sounds complicated? Well, there’s a much easier way to upload files with RAP 1.4! We’ve encapsulated the entire upload process in an implementation of the SWT FileDialog, which is also available in the incubator.

FileDialog1 Uploading files with RAP 1.4

To make it easy to use, we now provide an update site for the Incubator. To use the FileDialog in your application, all you have to do is to:

  1. include the bundles from the RAP Incubator repository http://download.eclipse.org/rt/rap/1.4/incubator/ in your RAP 1.4 target platform, and
  2. add a bundle dependency to org.eclipse.rap.rwt.supplemental.filedialog to your project (yes, you have to use Require-Bundle here because this bundle contributes a class to the org.eclipse.swt.widgets package, effectively creating a split-package).

That’s all. Now you can use the FileDialog just like in SWT:

  FileDialog fileDialog = new FileDialog( shell, SWT.TITLE | SWT.MULTI );
  fileDialog.setText( "Upload Files" );?
  fileDialog.setAutoUpload( true ); // This API will change, see below!
  fileDialog.open();
  String[] fileNames = fileDialog.getFileNames();

After uploading, the dialog closes and the variable fileNames contains the absolute file names of the uploaded files on the server’s file system. There’s an auto-upload feature that is really nice (I think it should be the default) – with autoUpload on, the upload starts immediately after file selection. A user can still press Cancel to prevent the application from using the uploaded files.

Note: Please note that this stuff is in the incubator and not part of the 1.4 release. The API and implementation may (and will) have to change and mature over time. However, if you use the latest version from 1.4/incubator site, you’ll always get a file dialog that will work with RAP 1.4. The server-side upload receiver and the required Apache bundles are also included.

We hope you enjoy these new features. Please try them out, tell us what you think, open bugs for the new stuff, and help us improving them.

Kudos to our new RAP committers Austin Riddle and Cole Markham who created this great new feature!

Update: I mistakenly left out the “.rwt.” from the bundle namespace in the original post, the bundle names are fixed now in the text.

Update: The 1.4 incubator repository has been updated with a newer version of the file dialog that is compatible with RAP 1.4. This update fixes the problem with missing file names mentioned in the comments.

on Jun 20th, 2011Using OSGi services to single-source an RCP and RAP Application

Probably one of RAP’s best known features is its single-sourcing capabilities. Some time ago we created a guide on Single-Sourcing RCP and RAP applications. The guide recommended a technique where a facade and fragments were used to invoke the RCP or RAP implementation during runtime. With this post I want to show you how to achieve the same the OSGi way.

For single-sourcing a RAP or RCP application, its straightforward to use the power of OSGi because it’s included in both platforms out-of-the-box. OSGi has a central concept called services which are simply POJOs and are used to allow communication between modules. And, you can register or resolve services at any time in your code.

The basic Idea behind using OSGi services for single-sourcing is as follows. We need to extract all the things that vary into separate, platform specific bundles. To use the different implementations, we have to create an interface in a “common” bundle that contains the methods we want to use. The platform specific bundles have to register an implementation of this interface as a service. In the “common” bundle we can reference the registered services and use them to get the platform specific stuff. More specifically, we register a RAP implementation in a “rap” bundle and an RCP implementation in an “rcp” bundle. The only thing we need to do then is to start the right bundles on the associated platform to get the right service.

With this solution we can extract the platform specific stuff into separate bundles and we don’t have to rely on fragments. So enough talking. Let’s look at some code. I decided to create a very simple single-sourcing interface which can be used to get the WidgetUtil.CUSTOM_VARIANT constant value. This constant exists only in RAP so, it’s a good example for showing how to handle the differences.

public interface ISingleSourcingService {
  String getCustomVariantString();
}

I have created three bundles: one that contains the application which is entitled “com.eclipsesource.app” and one for each platform. These are called “com.eclipsesource.app.rap” and “com.eclipsesource.app.rcp”. Both platform bundles implement the interface.
RAP:

  @Override
  public String getCustomVariantString() {
    return WidgetUtil.CUSTOM_VARIANT;
  }

RCP:

  @Override
  public String getCustomVariantString() {
    // There are no custom variants in RCP
    return "";
  }

And both bundles are registering the service in their Activator during the start method call.

  public void start( BundleContext bundleContext ) throws Exception {
    Activator.context = bundleContext;
    registration = context.registerService( ISingleSourcingService.class.getName(),
                                            new RAPSingelSourcingService(),
                                            null);
  }

When it comes to using the service in the common “app” bundle we can use a ServiceTracker to get the service implementation (you can also use DS).

  private ISingleSourcingService getSingleSourcingService() {
    // We use a tracker to get the service. We also can use DS to get it.
    Bundle bundle = FrameworkUtil.getBundle( getClass() );
    BundleContext context = bundle.getBundleContext();
    ServiceTracker tracker
      = new ServiceTracker( context,
                            ISingleSourcingService.class.getName(),
                            null );
    tracker.open();
    ISingleSourcingService service = tracker.getService();
    tracker.close();
    return service;
  }

The only thing we have to do now is to create two launch configurations which contain the associated platform-specific bundle.

That’s it! You can find the sources in this github repository. Have fun using OSGi services to single-source applications.

 

on May 13th, 2010Using Equinox Security in RCP and RAP

I finally had the time to care about one of my outstanding tasks – provide a tutorial and example how to use Equinox Security. While the tutorial was initially targeted for RAP users, I also added a launch config and a target definition for RCP as the code is the same for both runtimes. The tutorial will provide some hints and pointers how to setup your login procedure, like shown below:

rapsec login Using Equinox Security in RCP and RAP

After logging in (hint, hint), you’re able to inspect the currently active Subject. I made up this example to be as simple as possible to demonstrate the key concepts of Equinox Security, and not the ones from RAP/RCP.

rapsec subject Using Equinox Security in RCP and RAP

As I said, you can either choose between RAP as runtime (above) or RCP (below).

rcpsec subject Using Equinox Security in RCP and RAP

In addition to the authentication mechanism, I wrote a pretty simple LoginModule to show how to connect your authentication process to an alternative backend (eg. LDAP, Kerberos, …).

As I put the tutorial into the Eclipse wiki, I encourage everyone to extend the tutorial with hints, tricks or ideas what you can do with Equinox Security. Hope the tutorial helps to get up to speed how to use secure your RCP/RAP applications.

on Apr 20th, 2010Drawing with RAP? Yup!

I have to admit, I’m a little nervous what happens with the RAP community after this post. At least for me, the last days were pretty exciting. Some days ago, Ivan from the RAP team committed the initial support for a GC (GraphicsContext) for RAP. Currently restricted to the Canvas widget, the GC provides thousands of new use cases for RAP applications. The work by Ivan and Tim is just gorgeous and will help many developers to single-source their applications with even less exceptions. In case you want to try it out in this second without reading further, just fire up the RAP Examples demo and draw something yourself icon smile Drawing with RAP? Yup!

rap canvas demo1 Drawing with RAP? Yup!

Credits for the picture above goes to Holger with the aim to come up with a new RAP project logo icon wink Drawing with RAP? Yup! After using the GC the first time in the Examples demo, I thought about other possibilities to test the new GC. My first thought: custom widgets? Tired of writing custom widgets in JavaScript? Get your Canvas and single-source your custom widget with RCP by writing an owner-draw widget. But as it was late in the night, I decided to just reuse some existing owner-drawn widgets like those we can find in the Nebula project. After getting the PShelf widget from CVS, it was only a matter of seconds until I started my first RAP application using an owner-drawn Nebula widget:

rebula pshelf Drawing with RAP? Yup!

And I think I know what most of you are currently thinking – Draw2D, GEF and GMF on RAP? To keep it and short and simple: No! While it may be possible to single source Draw2D with the exisiting Canvas, I’m pretty sure it will not scale. The way Draw2D is implemented will cause major performance problems with the browser-side Canvas widget. As I said, it may be possible but not really preferable. For supporting Draw2D the right technology on the client-side is there. Only on the server-side we would need APIs that entirely hide the GC. Thus we could directly translate from one vector-based technology to the other.

I’m pretty excited to see how the community can profit from the new Canvas implementation. Want to try it out? Either get the current RAP runtime from CVS or wait some days until we can publish RAP M7 (which has several other cool new & noteworthy items).

on Apr 18th, 2010Name Your Workspaces

Here’s a nice Helios feature that comes in handy when you often work with multiple workspaces simultaneously (as we recommend for developing single source application with RCP and RAP). If you do, you probably know this which-is-which guessing when looking at your taskbar (or window switcher):

WithoutNames Name Your Workspaces

How can you distinguish your Eclipse instances? How can you tell in which workspace you are editing? There is a commandline parameter -showlocation that appends the workspace location to the window title – not very helpful either. Now since Helios M6, you can give your workspace a name in the Workspace preference page:

PreferencesCutted Name Your Workspaces

This name is then displayed in the window title:

WithNames2 Name Your Workspaces

Much better, isn’t it?

on Mar 22nd, 2010EMF and RAP – what a lovely pair

During the last weeks, Kenn and I worked together to support EMF generated editors running on RAP. I’m always mesmerized by how effective such synergies can be used when people from different teams work together for a bigger goal. Kudos to Kenn for his great work in EMF by refactoring the EMF UI bundles (namely o.e.emf.ui.common and o.e.emf.ui.edit) in order to single-source them. But what does that mean for the community?
rapemf e1269224344251 EMF and RAP   what a lovely pair
Go out, grab EMF & RAP M6 from Helios, get your model ready, fire up properties view and switch “Rich Ajax Platform” to true. Hit the magic “Generate All” button and you’re done – an EMF backed RAP application.
emfrapapp 300x210 EMF and RAP   what a lovely pair
For the details, please refer to the EMF/RAP integration wiki page.
In case you want to see what else is going on in the RAP space right now, I’ll be giving a RAP 1.3 N&N talk tomorrow at EclipseCon. Hope to see you there!

on Nov 27th, 2009Drag and Drop in Eclipse RAP

Support for drag and drop just made it into the RAP source code repository. You can use the same API as known from SWT and thus re-use even more code when single-sourcing RCP applications.
It will be available in the M4 build. In the meanwhile you can check out the sources from CVS and explore the new functionality online (go to the List page).

dnd Drag and Drop in Eclipse RAP

There are still some things left to do, for more details see this bug. We would be very happy to gain feedback about how your existing drag and drop code works on RAP. In case something doesn’t work as expected, please drop us a line or open a bug.

on Nov 23rd, 2009EclipseRT & RAP around the world

We’re all looking forward to talk about EclipseRT, Equinox and RAP at the DemoCamps around the world. In case you want to catch us and talk about Eclipse and related topics, just join one of the DemoCamps near you. Besides many other interesting talks, we’ll mostly cover EclipseRT, RAP and p2.

Eclipse camp EclipseRT & RAP around the world

Ottawa, ON, Canada – November 24 – Jeff McAffer (EclipseRT)
Braunschweig/Hanover, Germany – November 25 – Benjamin Muskalla (RAP)
Stuttgart, Germany – November 26 – Jordi Boehme Lopez (p2)
Kaiserslautern, Germany – November 26 – Holger Staudacher (RAP)
Frankfurt, Germany – November 26 – Benjamin Muskalla (EclipseRT,RAP)
Vienna, Austria – November 30 – Chris Anisczcyk and Jeff McAffer (RAP,EclipseRT)
Karlsruhe, Germany – December 3 – Markus Knauer, Benjamin Muskalla (EclipseRT)
Hamburg, Germany – December 4 – Jochen Krause (RAP)

I’m really looking forward to see you at the DemoCamps, as always it tends to be a lot of fun!

on Nov 17th, 2009Spread Sheet in the RAP Incubator

I am very pleased to see that the first code arrived in the RAP incubator project. The contribution consists of the very early steps towards a spread sheet component.

spread sheet Spread Sheet in the RAP Incubator

It is still in the proof of concept phase. The goal so far was to find out whether a spread sheet that is composed of existing widgets could work with regard to performance and usability. This seems to work out rather well. As a consequence of composing the spread sheet of existing widgets the same code runs on SWT as well.

In case you whish to play around with it or even contribute, the source code can be obtained from CVS and resides in the incubator/spreadsheet module.

© EclipseSource 2008 - 2011