blob: 02572c455ecbc21fc438cdaa21f92556ea52e936 [file] [log] [blame]
<div>
<h2>New Web Client Services</h2>
<p>
Based on the Client API that has been introduced in M2, some new client services have
been introduced:
</p>
<h3>JavaScriptLoader service</h3>
<p>
If a custom component requires additional JavaScript code on the client, the JavaScriptLoader
can be used to load a JavaScript file just before the component uses it.
The JavaScriptLoader will ensure that the file is loaded only once, even if <em>require()</em>
is called subsequently.
</p>
<pre class="lang-java">
JavaScriptLoader loader = RWT.getClient().getService( JavaScriptLoader.class );
loader.require( "rwt-resources/myComponent/MyFile.js" );
</pre>
<h3>ClientInfo service</h3>
<p>
The ClientInfo service provides additional information about the client that is connected to the
current UI session.
In this version, the service provides the client's locale and its timezone offset in minutes.
Unfortunately, it's not possible to obtain the actual timezone region from the browser.
</p>
<pre class="lang-java">
ClientInfo clientInfo = RWT.getClient().getService( ClientInfo.class );
int timezoneOffset = clientInfo.getTimezoneOffset();
Locale[] locales = clientInfo.getLocales();
</pre>
<h3>UrlLauncher service</h3>
<p>
The UrlLauncher service allows to open any URL (websites, files, "mailto", etc.) without
influencing or leaving the application. Popup blocker may ask the user for permission before
a new window is opened.
</p>
<pre class="lang-java">
UrlLauncher launcher = RWT.getClient().getService( UrlLauncher.class );
launcher.openURL( "http://www.eclipse.org/" );
launcher.openURL( "mailto:someone@nowhere.org" );
</pre>
<p>
Please use this new client service instead of the deprecated <em>ExternalBrowser</em>.
</p>
<h3>BrowserNavigation service</h3>
<p>
The BrowserNavigation service provides support for the browser's back/forward buttons and
deep linking. It's a complete replacement for the removed class BrowserHistory.
</p>
<pre class="lang-java">
BrowserNavigation navigation = RWT.getClient().getService( BrowserNavigation.class );
navigation.pushState( "cars", "Car selection" );
</pre>
<h2>API Changes</h2>
<h3>Prefix “I” removed from interfaces</h3>
<p>
The prefix “I” in interface names like <em>IEntryPoint</em> is a heritage from the Eclipse
platform.
This deviates from the naming pattern used in SWT and other libraries, and also from the Java
class library.
Since it is not even used consistently in RAP, we're removing the prefix from all interfaces.
</p>
<h3>Graphics deprecated</h3>
<p>
The class <em>Graphics</em> had been used to create <em>shared</em> instances of resources like
<em>Color</em> and <em>Font</em> before resource constructors were introduced in 1.3.
This practice is problematic because instances created using these methods throw an exception
when trying to dispose them. Moreover, they cannot be garbage collected.
In RAP 2.0, resources should only be created using the constructors
of <em>Color</em>, <em>Font</em>, <em>Cursor</em>, and <em>Image</em>.
</p>
<p>
Graphics also provided methods for test size measurement. We expect that these methods are
hardly used by application code and can be replaced by SWT's <em>GC</em> API.
To measure a string in a given font, create a GC, set the font, and call the GC methods
<em>stringExtent</em> or <em>textExtent</em>. Don't forget to dispose of the GC afterwards.
</p>
<h3>Service store deprecated</h3>
<p>
The service store is used internally by the framework to store data in the scope of a request.
Application developers shouldn't really need this store anymore.
If an application needs to store any information in the request scope, it should use the
request object directly, i.e. <code>RWT.getRequest().setAttribute(...)</code>.
</p>
<h3>Session store replaced by UI session</h3>
<p>
When working with RAP, you have to deal with two different types of sessions: the servlet
container's <em>HttpSession</em> and RAP's <em>UISession</em> (formerly known as session store).
Both sessions have a different scope and a different purpose.
In recent projects we've noticed that the relationship between the HTTP session and RAP's
“session store” led to confusion. By renaming the session store to UI session we hope to make it
more clear that both are sessions with a different scope and meaning.
Here's some background:
</p>
<p>
<strong>The HTTP session</strong> is managed by the servlet container which recognizes the user
with the help of a Cookie or URL rewriting.
It has a configurable timeout, after which a user has to sign in again.
The HTTP session is the place to store user-specific information.
</p>
<p>
<strong>The UI session</strong> is built on top of the HTTP session, but has a shorter lifetime.
A new UI session is started every time a user accesses an entrypoint and it lives as long this
UI is being used. When the user accesses another entrypoint, this results in a new UISession,
but the HttpSession will be the same.
The UI session is the place to store information that is related to the current
<em>instance</em> of an application's UI.
It can now also be used to access UI-session-scoped instances such as the <em>Client</em>
and the locale.
</p>
<p>
The interface <em>ISessionStore</em> has been renamed to <em>UISession</em>. The types
<em>SessionStoreListener</em> and <em>SessionStoreEvent</em> have been renamed accordingly.
</p>
<p>
In addition to the <em>get/setAttribute</em> methods, <em>UISession</em> also provides access
to the <code>Client</code> instance and the <code>Locale</code>.
Actually, <code>RWT.getClient()</code> is now a shortcut for
<code>RWT.getUISession().getClient()</code>.
The same is true for <code>RWT.getLocale()</code> and <code>RWT.setLocale( locale )</code>.
</p>
<h3>Application store replaced by Application context</h3>
<p>
The new <em>ApplicationContext</em> represents the running instance of a RAP application, it is
shared by all UI sessions. This interface replaces IApplicationStore, it can be used to store
shared data, and also to obtain application-scoped services such as the resource manager.
</p>
<p>
Just like the UISession is built on the servlet container's HttpSession, the ApplicationContext
is built on the <em>ServletContext</em>, and its life cycle is also bound to lifetime of the
servlet context.
We chose the name Application<em>Context</em> to highlight this analogy.
</p>
<p>
The interface <em>IApplicationStore</em> has been renamed to <em>ApplicationContext</em>.
An instance can be acquired from <code>RWT.getApplicationContext()</code> which replaces
the old method <code>RWT.getApplicationStore()</code>.
</p>
<p>
In addition to the <em>get/setAttribute</em> methods, <em>ApplicationContext</em> has accessor
methods for the resource manager and the service manager.
Actually, <code>RWT.getResourceManager()</code> is now simply a shortcut for
<code>RWT.getApplicationContext().getResourceManager()</code>.
</p>
<h3>Service handlers</h3>
<p>
The interface <em>ServiceHandler</em> has been changed.
The <em>service</em> method now provides two parameters <em>request</em> and <em>response</em>
to the implementation.
Developers don't have to obtain the request and response objects from static methods anymore.
</p>
<p>
The <em>ServiceManager</em> has got a new method <em>getServiceHandlerUrl( String )</em>.
Developers should use this new method to obtain the URL to access a service handler instead
of assembling the URL manually.
</p>
<h3>New Server Push API to replace UICallBack</h3>
<p>
The class <em>UICallBack</em> represents RAP's mechanism to “push” UI updates to the client
when these updates occur outside of a request.
It can be activated and deactivated using an ID, in order to allow different parties to activate
the the push independently.
We noticed that users had trouble to understand the idea behind these IDs,
so we tried to come up with a new API.
</p>
<p>
We chose to call the system <em>server push</em>, which is the common name for technologies that
simulate a push update from an HTTP server to a client.
To activate the server push, you can create a new <em>ServerPushSession</em> and start it.
The push session can be stopped when it is no longer needed
(in contrast to UICallBack, this can now be done from any thread).
As long as there are any push sessions running, the framework will keep the server push system
active.
</p>
<h3>BrowserHistory replaced by BrowserNavigation service</h3>
<p>
As mentioned above, the <em>BrowserHistory</em> and related classes have been replaced by
the more general <em>BrowserNavigation</em> client service.
All features of BrowerHistory are retained, view the
<a href="migration-guide/">migration guide</a> for a code example.
</p>
<p>
Besides the new name, there is one important change:
The <em>BrowserNavigationListener</em> (formerly <em>BrowserHistoryListener</em>) is now
informed of all changes in the URL's fragment identifier (the characters following the “#”),
even if the change was not triggered by the history back/forward buttons (<?=bug(394401)?>).
</p>
<p>
You use the BrowserNavigation to navigate between <em>states</em> in your application.
With <em>pushState()</em>, you push a new state to the (history) stack, and navigation events
provide their state in <em>getState()</em>.
This new terminology will allows us to add more navigation features to this service
that are not directly related to history.
</p>
<h2>IApplication, again</h2>
<p>
In M3, we reversed the relationship between entrypoints and branding extensions, which also
requires a change for applications that use the <em>IApplication</em> interface for single-sourcing.
Our solution was to support the parameters <em>path</em> and <em>brandingId</em>
added to application extensions.
It turned out that this approach lead to problems (<?=bug(394805)?>) so we had to change it again.
</p>
<p>
Application extensions can now be referenced by an <em>entrypoint</em> extension using the new
parameter <em>applicationId</em>.
To make an existing application extension available in RAP, you have to create a new entrypoint
extension and specify the id of the application extension instead of an EntryPoint class:
</p>
<pre class="lang-xml">
&lt;extension point="org.eclipse.rap.ui.entrypoint"&gt;
&lt;entrypoint id="example.application.entrypoint"
path="/example"
brandingId="example.branding"
<strong>applicationId="example.application"</strong> /&gt;
&lt;/entrypoint&gt;
&lt;/extension&gt;
</pre>
<p>
This allows to use existing application extensions without modification.
Path and branding can be specified in the same way as for all other entrypoints.
</p>
<h2>Settings</h2>
<h3>Development Mode</h3>
<p>
During development, it's recommended to start RAP in <em>development mode</em>.
In this mode, the JavaScript for the web client is not compressed and potential client-side
errors will not be caught.
This new setting replaces the old <em>clientLibraryVersion</em>, which has been used for this
purpose before.
In the RAP Launcher, you'll find a new option to enable the development mode:
</p>
<p>
<img class="framed" title="Development mode" src="images/RAPLauncher-dev-mode.png" />
</p>
<p>
In OSGi launch configurations, please replace the VM parameter
<code>-Dorg.eclipse.rwt.clientLibraryVersion=DEBUG</code> with
<code>-Dorg.eclipse.rap.rwt.developmentMode=true</code>.
</p>
</div>