The Eclipse Rich Client Platform (RCP) provides an extremely flexible, feature-rich framework for thick clients. But one drawback is the ability to easily link to business objects in an RCP application from other sources. It would be helpful if a user were able to click a link in another application and be taken to the RCP application with a business object referred to in the link already open. For example, imagine an RCP application used to process expense claims. Perhaps a report for overdue reimbursements is generated and published as a spreadsheet (or on an intranet, or as a rich-text document, or as an e-mail, or as ⦠well, you get the picture). The report probably has a reference number for each overdue claim. Instead of forcing the consumer of that report to copy and paste the reference number into a search dialog within the RCP application, the report could contain a hyperlink URL that will launch the RCP application, taking the user directly to that expense claim. This article will explain how to accomplish just that.
Readers should have experience writing Eclipse plug-ins, as well as general knowledge of the Windows® registry and the TCP protocol. While this article provides specific examples for a Windows operating system, the same function can be achieved on other operating systems. See Resources for more information.
Let's take a look at the big picture of how the solution works once it's in place. Then we will break it down and discuss how to implement each of the parts.
Follow along with the flow in Figure 1:
- Assume that a user already has the RCP application open on his desktop.
- Then suppose this user receives an e-mail in his favorite mail client containing the link rcp://claim=25222 — a reference to an overdue claim (1).
- The user clicks the link, which launches the user's default browser to handle the request (2).
- The browser knows that it cannot natively open this URL, so it consults with the Windows registry to determine how the action should be delegated (3).
- The registry looks up the rcp:// protocol and determines that there is a batch file bound to it (4).
- This batch file is executed (5), which triggers a stand-alone Java™ client (6), captures the URL's parameters, and makes a local TCP call to a TCP server embedded in the RCP application for this purpose (7).
- The TCP server handles parsing the parameters from the URL (i.e., claim=25222) and requests the RCP application to open the corresponding business object (8).
- The user is then presented with the requested business object in the RCP application UI (9).
Figure 1. Flow control when opening an RCP application using a URL
There are many steps involved in this process, but fortunately, each is relatively straightforward and can be adapted to your environment and applications. Some finishing touches help with details like bringing your RCP application into focus in Windows.
Registering your application to a URL protocol in Windows
Windows uses entries in the registry to recognize valid URL protocols and to determine
what application a request with a particular protocol should be sent to. To enable our
RCP application to respond to URLs, a key must be created under the HKEY_CLASSES_ROOT
hive. The key name must match the protocol being created. In this article, we are using
an "rcp://" URL protocol, so the key must be named "rcp." The default string value
under this key corresponds to the display name of the new protocol. Under the "rcp" key,
we must also create a shell\open\command key with a string value containing the path to
the application Windows should open when it receives an "rcp://" request.
In this article, we will point Windows to a batch file (see "The batch file"). The string value for this key should also have a
%1 appended to the end of it, telling Windows to pass the URL query string to your
application. This is how we will pass context information, such as the particular
business object to open, to the RCP application.
The following Windows batch file snippet will create the appropriate keys in your
registry, with an "rcp://" protocol, which will launch Notepad. To customize the script,
replace all instances of rcp with the protocol you wish to use and
C:\Windows\Notepad.exe with the full path to the file you want Windows to execute.
Listing 1. Batch file code to register a URL protocol in the Windows registry
reg add HKCR\rcp /ve /d "URL:RCP Protocol"
reg add HKCR\rcp /v "URL Protocol"
reg add HKCR\rcp\Shell\Open\Command /ve /d "C:\Windows\Notepad.exe %%1"
|
Note: If you prefer updating your registry manually with regedit,
see Resources for an article describing how to do this.
Once the URL protocol has been registered, you can test it out by typing rcp:// into your browser's address bar and clicking Go.
Notepad (or the file you chose to register) should now be open.
Other operating systems, such as Linux®, delegate the job of registering URL protocols to the browser. See Resources for instructions to register a URL protocol in Mozilla Firefox.
Once you have tested that the rcp:// protocol we defined opens Notepad as expected, try remapping the rcp:// protocol to a batch file that will launch the TCP client. To do this, change the value for the HKCR\rcp\Shell\Open\Command registry entry. See Listing 2 for an example of how the batch file that launches the TCP client might look.
Listing 2. Batch file code to launch a TCP client
@echo off
set JAVA_BIN=c:\<insert your java directory here>
cd <root location of your URIClient application's package.>
%JAVA_BIN%\java.exe com.company.uri.URIClient %1
EXIT
|
Table 1. Annotations for Listing 2
| Line number | Annotation |
|---|---|
| 2 | For example, set JAVA_BIN=C:\Program Files\IBM\Java50\jre\bin
|
| 3 | For example, the directory containing the TCP client's parent package |
| 4 |
URIClient is described below |
As described in the overview, the user's action of clicking on the rcp:// hyperlink ultimately fires off a TCP request that hits a TCP server embedded in the RCP application. This solution involves a bit of network programming, but fortunately, the Java API takes care of the details of the TCP communication for us.
In our example, the TCP server is launched in an RCP plug-in's startup code and waits for a call from the TCP client. The call will be from the client to a server on its localhost, made on a port number known to both the client and the server. The client passes the details of the URL request to the server over a Java socket. The TCP server is then responsible for executing the appropriate RCP actions to open the business object. These actions will be specific to the particular application, but we'll deal with that in "Handling the business object."
For our demonstration, we use four Java classes that live in the com.company.uri package.
- URIClient.java
- A stand-alone TCP client triggered by the URL selection
- URIServer.java and URIServerThread.java
- Comprise a TCP server embedded in our RCP application
- URIConstants.java
- Some constants shared between client and server
These Java files are available for download.
The TCP server —
URIServer and URIServerThread
-
URIServeris responsible for listening for requests. As it detects a request, it spawns a thread ofURIServerThreadthat will handle the connection with the TCP client.
-
URIServercan be launched in a plug-in's initialization class. Each RCP plug-in may have an associated startup class that extends org.eclipse.ui.plugin.AbstractUIPlugin. This class'sstartmethod can initializeURIServer.
- Our RCP application spawns
URIServerby calling newURIServer().start(), launching the sever in its own thread and preventing the RCP application from blocking with waiting TCP requests.
- Our
URIServerThreadhandles logic for opening the business application. This will be discussed in detail in "Handling the business object."
- Note that both
URIServerandURIServerThreadextend java.lang.Thread.
Listing 3. Sample plug-in start method
/**
 * This method is called upon plug-in activation, starts up URIServer
Â
*/
 public void start(BundleContext context) throws Exception {
 super.start(context);
 new URIServer().start();
}
|
The TCP client application —
URIClient
- The TCP client is deployed as a stand-alone Java file not referenced by the RCP
application.
URIClient.main()is executed when triggered by the batch file associated with the rcp:// protocol.
- The constructor passes the URL parameters to the
tcpConnectmethod. This method constructs a socket targeted to the TCP server on the localhost at a host number known both to the client and server throughURIConstants.
- Tip: Consider that while the Java client isn't referenced by an RCP plug-in, deploying it within a plug-in allows the code to be updated through the Eclipse updater framework. If it were to reside outside of a plug-in, deploying code updates becomes more difficult.
- How do the TCP client and server communicate? Assume that the RCP application and,
therefore, the TCP server, is already running. As we have explained, the registry and
batch file handle launching the TCP client.
URIClientwill strip off the parameters (i.e., claim=25222) and will attempt to make a socket connection to theURIServerat a port number known to the client and server.
- Now that the connection's been made, the server will acknowledge the client and
request further instruction by sending a literal stored in the constants file, and known
to the client and server. In the example, the server sends the literal
sendAction. Once the client receives this instruction, it responds by sending the server the name-value pair — in this case, "claim=25222" — containing the information about the desired business object. At this point, the client and server terminate their connections. Of course, as long as the server knows what to expect, the specific name-value pairs being sent can be customized.
- It's now up to the TCP server to parse the arguments and launch the appropriate actions.
Ideally, the TCP client and server that have been described above could both be launched by the RCP application, eliminating the need for a stand-alone Java application and reducing the number of deployed artifacts. Whenever the RCP application is triggered using a URL, conventional application startup would be attempted using the application's .exe or batch-file starter. However, early on in the application's initialization, the application would check whether an instance of it is already running. If the application is already running, a TCP client would be initialized and pass the URL arguments to the embedded TCP server waiting to receive such notification in the running RCP application. The server would handle opening the respective business object, as in the example above. However, if the RCP application is not yet running, it would proceed to be opened at this point, and it would use the URL arguments as RCP program arguments to open the appropriate business object.
Embedding the TCP client in the RCP application may not be possible if you are unable to access your application's early startup code, such as if you are deploying a plug-in on top of an existing application. For this reason, this article has described the more flexible approach of a stand-alone TCP client.
As noted, our URIServerThread handles opening the business
object. In the listing provided here, for simplicity, the code launches a dialog that
shows the business object ID provided on the URL. In a real application, we would do
something far more interesting, like invoke an Action that
will find and open our business object that has the identifier provided.
Eclipse has a single thread for managing the user interface, and some SWT API methods
may only be called from that thread. (see Resources for more
information). Because our URIServerThread is running as its
own thread, we need to consider this limitation. In order for a spawned thread to call
back to the Eclipse workbench, it must use methods in the Display object to gain access to the UI thread. If this is not done,
an ERROR_THREAD_INVALID_ACCESS error will be thrown at runtime.
By default, clicking on the rcp:// link will indeed open the business object in an RCP
application, but the RCP application may be hidden behind other applications, such as
the one that contained the rcp:// link. It is important that we bring the RCP
application into focus. In the URIServerThread listing,
notice the following statements that are responsible for bringing the RCP application
to the user's attention:
shell.setActive(); shell.setMaximized(true); shell.setVisible(true); Â shell.setFocus(); |
We have not mentioned error handling, but this is clearly necessary in several places. First, TCP communication brings along with it try/catch blocks that need to be handled appropriately. Also, one needs to ensure that cases are handled for various malformed URLs, especially to protect against intentional attacks.
You may have noticed that delegating resolution of the rcp:// protocol to the Windows default browser has the unwanted side effect of leaving a browser window open. While not ideal, this is something we have tolerated. We would be eager to hear your suggestions as to how to prevent this, especially in an environment where the RCP application is distributed widely and tweaking the user settings in Firefox might not be feasible.
The process described details a framework for opening a single business object in your RCP application using a URL. However, there are possibilities for extending this idea in interesting ways. For instance, several name-value pairs could be included in the URL to perform more sophisticated operations. Consider an order-entry application, where a URL could be used to pre-populate an order with certain products. Following these steps, any action defined in an RCP application can be accessed from any application simply by clicking a link.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample code | os-eclipse-rcpurl.source.zip | 4KB | HTTP |
Information about download methods
Learn
-
"Registering
an application to a URL protocol in Windows" describes how to add a new key, along
with the appropriate keys and values, to
HKEY_CLASSES_ROOT. -
The article "Register
protocol" describes how to register an application to a URL protocol in Firefox.
-
See the Eclipse documentation to
learn how to access Eclipse's display from a spawned thread in
org.eclipse.swt.widgets.Display Class Display.
-
Check out the "Recommended Eclipse reading list."
-
Browse all the Eclipse content on developerWorks.
-
New to Eclipse? Read the developerWorks article "Get started with Eclipse Platform" to learn its origin and architecture, and how to extend Eclipse with plug-ins.
-
Expand your Eclipse skills by checking out IBM developerWorks' Eclipse project resources.
-
To listen to interesting interviews and discussions for software developers, check out developerWorks podcasts.
-
Stay current with developerWorks' Technical events and webcasts.
-
Watch and learn about IBM and open source technologies and product functions with the no-cost developerWorks On demand demos.
-
Check out upcoming conferences, trade shows, webcasts, and other Events around the world that are of interest to IBM open source developers.
-
Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products.
Get products and technologies
-
Check out the latest Eclipse technology downloads at IBM alphaWorks.
-
Download Eclipse Platform and other projects from the Eclipse Foundation.
-
Download IBM product evaluation versions, and get your hands on application development tools and middleware products from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.
-
Innovate your next open source development project with IBM trial software, available for download or on DVD.
Discuss
-
The Eclipse Platform newsgroups should be your first stop to discuss questions regarding Eclipse. (Selecting this will launch your default Usenet news reader application and open eclipse.platform.)
-
The Eclipse newsgroups has many resources for people interested in using and extending Eclipse.
-
Participate in developerWorks blogs and get involved in the developerWorks community.
Comments (Undergoing maintenance)





