<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Angelo&#039;s Blog</title>
	<atom:link href="http://angelozerr.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://angelozerr.wordpress.com</link>
	<description>@Repository about my passion</description>
	<lastBuildDate>Fri, 13 Jan 2012 23:27:48 +0000</lastBuildDate>
	<language>fr</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='angelozerr.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Angelo&#039;s Blog</title>
		<link>http://angelozerr.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://angelozerr.wordpress.com/osd.xml" title="Angelo&#039;s Blog" />
	<atom:link rel='hub' href='http://angelozerr.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Eclipse Nebula Pagination Control</title>
		<link>http://angelozerr.wordpress.com/2012/01/06/nebula_pagination/</link>
		<comments>http://angelozerr.wordpress.com/2012/01/06/nebula_pagination/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 17:13:50 +0000</pubDate>
		<dc:creator>angelozerr</dc:creator>
				<category><![CDATA[Eclipse Nebula]]></category>
		<category><![CDATA[Eclipse RAP]]></category>
		<category><![CDATA[Eclipse RCP]]></category>
		<category><![CDATA[Nebula Pagination]]></category>
		<category><![CDATA[Spring Data]]></category>

		<guid isPermaLink="false">http://angelozerr.wordpress.com/?p=5471</guid>
		<description><![CDATA[In business application with large data, display data in a table with navigation page can be really helpful. In our XDocReport project, we need this feature in our Eclipse RCP/RAP XDocReport application for instance to select resumes to open in the Search Resume Dialog : This last screenshot is the resume search dialog in WEB [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=5471&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In business application with large data, <strong>display data in a table with navigation page</strong> can be really helpful. In our <a href="http://code.google.com/p/xdocreport/">XDocReport</a> project, we need this feature in our <a href="http://xdocreport-rap.opensagres.cloudbees.net/xdocreport?startup=fr.opensagres.xdocreport.eclipse.ui.application">Eclipse RCP/RAP XDocReport</a> application for instance to select resumes to open in the Search Resume Dialog : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_rapresumesearch1.png?w=600" /></p>
<p>This last screenshot is the resume search dialog in WEB context (Eclipse RAP). Here a screenshot in fat client context (Eclipse RCP) : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_rcpresumesearch.png?w=600" /></p>
<p>After several search, it seems that there is no project which provides a SWT pagination control, which works with Eclipse RCP and RAP. So we decided to develop this control and give our code to <a href="http://eclipse.org/nebula/">Eclipse Nebula Project</a> with the <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=367064">bug 367064</a>. Today Nebula Team are voting if the project will be accepted or not. </p>
<p><span id="more-5471"></span></p>
<h2>Overview</h2>
<p>The <strong>Nebula Pagination Plug-Ins</strong> gives you the capability to <strong>paginate data list in any SWT Widgets</strong>. It <strong>works with Eclipse RCP and RAP too</strong>.</p>
<h3>Table pagination</h3>
<p>Nebula Pagination gives you the capability for instance to manage pagination in a SWT Table : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_graphicspageabletableexampleblue.png?w=600" /></p>
<p>This screen comes from org.eclipse.nebula.widgets.pagination.example.table.renderers.<strong>GraphicsPageableTableExample</strong>. Here the page navigation bar is drawn with SWT Graphics Context (GC), and you can change on runtime if you need the control style (or implement your own style). Here black style : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_graphicspageabletableexampleblack.png?w=600" /></p>
<p>and green style : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_graphicspageabletableexamplegreen.png?w=600" /></p>
<p>You can use another pagination navigation bar renderer. For instance here links renderer: (see org.eclipse.nebula.widgets.pagination.example.table.<strong>StringPageableTableExample</strong>) :</p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_stringpageabletableexample.png?w=600" /></p>
<p>Nebula Pagination provides another pagination renderer like <strong>Combo Page</strong> to choose the page, <strong>Scale Page</strong> to select a page, etc&#8230; Here a screenshot where you can see the whole pagination renderer (see org.eclipse.nebula.widgets.pagination.example.table.renderers.<strong>AllRenderersPageableTableExample</strong>) :</p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_allrendererspageabletableexample.png?w=600" /></p>
<p>The <strong>whole pagination renderer are synchronized with the pagination controller</strong>. For instance if you change the selected page in a pagination renderer, the other pages renderer will be synchronized with this new selected page.</p>
<h3>Table pagination&amp;sort</h3>
<p>You can manage sort with pagination like this (see org.eclipse.nebula.widgets.pagination.example.table.<strong>ModelSortPageableTableExample</strong>) : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_modelsortpageabletableexample.png?w=600" /></p>
<h3 id="ModelSortPageableTableWorkInProcessExample">Work In Process</h3>
<p>The load of the paginated list could take time. You can observe the before/end loading of the paginated list to display a &#8220;Loading&#8230;&#8221; message. If you launch org.eclipse.nebula.widgets.pagination.example.table.<strong>ModelSortPageableTableWorkInProcessExample</strong> and you click on a page index (here the 2 page is selected), a &#8220;loading&#8221; message display on the bottom of the table : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_modelsortpageabletableworkinprocessexample1.png?w=600" /></p>
<p>The load of the paginated list takes 1 second and display at end the time of the load of the data : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_modelsortpageabletableworkinprocessexample2.png?w=600" /></p>
<h3>Lazy loading</h3>
<p>Nebula Pagination is able to manage <strong>lazy table to load new items when last item of the table is selected</strong>  (see org.eclipse.nebula.widgets.pagination.example.table.lazy.<strong>LazyPageTableExample</strong>): </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_lazypagetableexample1.png?w=600" /></p>
<p>after selecting the last row, it load new data : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_lazypagetableexample2.png?w=600" /></p>
<h2>Plug-Ins</h2>
<p>Nebula Pagination contribution provides 7 Plug-Ins : </p>
<ul>
<li><strong>org.eclipse.nebula.widgets.pagination</strong> : Eclipse Nebula Pagination which provides abstract class to manage pagination and implementation of thoses classes with PageResult pagination structure. Eclipse Nebula Pagination  defines an IPageContentProvider to work with any Pagination structure (by default it works with Nebula PageResult, but you can use Spring Data Page structure if you wish (see org.eclipse.nebula.widgets.pagination.springdata).
  </li>
<li><strong>org.eclipse.nebula.widgets.pagination.example</strong> : sample with table pagination by using Nebula Pagination.
  </li>
<li><strong>org.eclipse.nebula.widgets.pagination.tests</strong> : tests of  Eclipse Nebula Pagination.
  </li>
</ul>
<p>And if you wish use Spring Data pagination structure : </p>
<ul>
<li><strong>org.eclipse.nebula.widgets.pagination.springdata</strong> : defines an  IpageContentProvider to works with Spring Data Page, Pageable.
  </li>
<li><strong>org.eclipse.nebula.widgets.pagination.example.springdata</strong> : same sample than org.eclipse.nebula.widgets.pagination.example but works with Spring Data structure.
  </li>
<li><strong>org.springframework.data.domain-only</strong> : Spring Data  with just Pagination structure.
  </li>
<li><strong>org.springframework.data.domain.collections</strong> : <a href="#SpringDataDomainCollections">Spring Data domain Collections</a> support.
  </li>
</ul>
<h2 id="NebulaPaginationWithoutSpringData">Nebula Pagination API (without Spring Data)</h2>
<p>To manage pagination with SWT table, Nebula Pagination provides a SWT Composite org.eclipse.nebula.widgets.pagination.<strong>PageableTable</strong>. The use of PageableTable is very easy but before explaining how to use it, it&#8217;s interesting to manage pagination at hand with the Nebula Pagination API (page controller etc) to understand more how to work PageableTable. The Nebula Pagination API could be used to manage pagination with another thing like Tree, <a href="http://nattable.org/drupal/">NatTable</a>, etc.</p>
<h3>Pagination in Table at hand</h3>
<p>This explanation is based on the sample org.eclipse.nebula.widgets.pagination.example.table.renderers.<strong>OneRendererPaginationTableAtHandExample</strong> : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_onerendererpaginationtableathandexample.png?w=600" /></p>
<p>Nebula Pagination works with a <strong>pagination controller</strong> which <strong>hold information about pagination and send events when information changes</strong>. The pagination controller is used to store information about pagination :</p>
<ul>
<li>the <strong>current page index</strong>: index of the selected page.
  </li>
<li>the <strong>page size</strong>: number items to display per page.
  </li>
<li>the <strong>total elements</strong>: the total elements of the paginated list.
  </li>
<li>the <strong>current sort information</strong>: the property name and direction of the sort.
  </li>
</ul>
<p>The <strong>controller fire events as soon as pagination information changes</strong> (ex: a new page is selected, sort change,etc). Those information can be observed by adding org.eclipse.nebula.widgets.pagination..<strong>IPageChangedListener</strong> to the controller. The pagination controller is designed with the class org.eclipse.nebula.widgets.pagination.<strong>PageableController</strong> which plays the role of the pagination request.</p>
<ol>
<li>At first you must create a pagination controller like this:<br />
<pre class="brush: java;">int pageSize = 10;
final PageableController controller = new PageableController(pageSize);</pre>
  </li>
<li>For pagination table, a listener is added to the pagination controller to refresh the table with paginated list. To load paginated list, you must implement org.eclipse.nebula.widgets.pagination.<strong>IPageLoader</strong> :
<p><pre class="brush: java;">package org.eclipse.nebula.widgets.pagination;

import java.util.List;

import org.eclipse.nebula.widgets.pagination.collections.PageResultLoaderList;
import org.eclipse.nebula.widgets.pagination.collections.PageResult;

/**
 * Classes which implement this interface provide methods which load paginated
 * list by using information about pagination (sort, page index etc) coming from
 * the {@link PageableController}.
 * 
 * &lt;p&gt;
 * If you wish to manage pagination with Java {@link List} in memory you can use
 * {@link PageResultLoaderList}.
 * 
 * &lt;/p&gt;
 * &lt;p&gt;
 * For better design {@link IPageLoader} should be implemented by the Service
 * Layer or DAO (Repository) layer. If you wish to manage pagination with JPA,
 * Spring Data JPA can be very helpful.
 * &lt;/p&gt;
 * 
 * @see http://www.springsource.org/spring-data
 */
public interface IPageLoader&lt;T&gt; {

  /**
   * Load the paginated list by using the {@link PageableController}
   * information about pagination (sort, page index etc) and returns a page
   * result which contains the paginated list and the total elements (ex:
   * {@link PageResult}, Spring Data Page, etc).
   * 
   * @param controller
   *            information about pagination.
   * @return a pagination structure which contains the paginated list and the
   *         total elements.
   */
  T loadPage(PageableController controller);

}</pre></p>
<p>The implementation of this interface must return the page result structure. Nebula Pagination provides a basic pagination page result org.eclipse.nebula.widgets.pagination.collections.<strong>PageResult</strong> which works with Java list : </p>
<p><pre class="brush: java;">package org.eclipse.nebula.widgets.pagination.collections;

import java.util.List;

/**
 * 
 * Page result used to store pagination result information :
 * 
 * &lt;ul&gt;
 * &lt;li&gt;the total elements&lt;/li&gt;
 * &lt;li&gt;the paginated list&lt;/li&gt;
 * &lt;/ul&gt;
 * 
 * @param &lt;T&gt;
 *            the type item of the paginated list.
 */
public class PageResult&lt;T&gt; {

	private final List&lt;T&gt; content;
	private final long totalElements;

	/**
	 * Constructor with the given paginated list and total elements.
	 * 
	 * @param content
	 * @param totalElements
	 */
	public PageResult(List&lt;T&gt; content, long totalElements) {
		this.totalElements = totalElements;
		this.content = content;
	}

	/**
	 * Returns the total amount of elements.
	 * 
	 * @return the total amount of elements
	 */
	public long getTotalElements() {
		return totalElements;
	}

	/**
	 * Returns the page content as {@link List}.
	 * 
	 * @return
	 */
	public List&lt;T&gt; getContent() {
		return content;
	}
}</pre></p>
<p>So you can create a page loader like this: </p>
<p><pre class="brush: java;">final List items = ...;
final IPageLoader&lt;PageResult&gt; pageLoader = new PageResultLoaderList(items);</pre></p>
<p>If you use <a href="http://www.springsource.org/spring-data/jpa">Spring Data JPA</a>, the page result structure can be org.springframework.data.domain.<strong>Page</strong> and implementation of the IPageLoader can call directly a repository interface (ex:  Page findAllPageable(Pageable pageable)). If you wish use Nebula Pagination with Spring Data, please read <a href="#NebulaPaginationWithSpringData">Nebula Pagination API (with Spring Data)</a>.</p>
</li>
<li>You can create your TableViewer with classic mean and synchronyse it with controller and pageLoader like this :<br />
<pre class="brush: java;">Table table = new Table(parent, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
...
TableViewer viewer = new TableViewer(table);
controller.addPageChangedListener(PageLoaderStrategyHelper.createLoadPageAndReplaceItemsListener(controller, viewer, pageLoader, PageResultContentProvider.getInstance(), null));
</pre></p>
<p>Here when controller changes (ex: page index changes, sort changes, etc), it call the pageloader which returns paginated list in the PageResult and the viewer is refreshed (viewer.setInput(page.gecontent()) with the sublist coming from the PageResult#getContent(). <strong>PageResultContentProvider.getInstance() </strong>is the org.eclipse.nebula.widgets.pagination.<strong>IPageContentProvider</strong> to tell that you wish works with page result org.eclipse.nebula.widgets.pagination.<strong>PageResult</strong>.</p>
<p>Now if you do :</p>
<p><pre class="brush: java;">controller.setCurrentPage(0)</pre></p>
<p>to set the current page index to 0, the controller will send an event to notify that page index has changed. In this case, page loader will be called to load paginated list and refresh the viewer.
  </li>
<li>At this step we can display navigation page with a renderer :
<p><pre class="brush: java;">ResultAndNavigationPageLinksRenderer resultAndPageLinksDecorator = new ResultAndNavigationPageLinksRenderer(parent, SWT.NONE, controller);</pre>
  </li>
<li>At this step, page links are drawn and you can click on page links to navigate to page and refresh the table. Now you can create columns and add sort by adding SortTableColumnSelectionListener to the column:<br />
<pre class="brush: java;">TableViewerColumn viewerColumn = new TableViewerColumn(viewer,
SWT.NONE);
...
viewerColumn.getColumn().addSelectionListener(new SortTableColumnSelectionListener(&quot;name&quot;, controller));
</pre></p>
<p>The constructor org.eclipse.nebula.widgets.pagination.table.<strong>SortTableColumnSelectionListener</strong> is called with &#8220;name&#8221; property to sort to Person#getName() property.
  </li>
</ul>
<p>Here the full code : </p>
<p><pre class="brush: java;">package org.eclipse.nebula.widgets.pagination.example.table.renderers;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.nebula.widgets.pagination.IPageLoader;
import org.eclipse.nebula.widgets.pagination.PageLoaderStrategyHelper;
import org.eclipse.nebula.widgets.pagination.PageableController;
import org.eclipse.nebula.widgets.pagination.collections.PageResult;
import org.eclipse.nebula.widgets.pagination.collections.PageResultContentProvider;
import org.eclipse.nebula.widgets.pagination.collections.PageResultLoaderList;
import org.eclipse.nebula.widgets.pagination.example.model.Address;
import org.eclipse.nebula.widgets.pagination.example.model.Person;
import org.eclipse.nebula.widgets.pagination.renderers.navigation.ResultAndNavigationPageLinksRenderer;
import org.eclipse.nebula.widgets.pagination.table.SortTableColumnSelectionListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

/**
 * This sample display a list of model {@link Person} in a SWT Table with
 * pagination banner displayed with Page Results+Page Links on the top of the
 * SWT Table. The 2 columns which display the list of {@link Person} can be
 * clicked to sort the paginated list.
 * 
 */
public class OneRendererPaginationTableAtHandExample {

	public static void main(String[] args) {

		Display display = new Display();
		Shell shell = new Shell(display);
		GridLayout layout = new GridLayout(1, false);
		shell.setLayout(layout);

		final List items = createList();

		Composite parent = new Composite(shell, SWT.NONE);
		parent.setLayoutData(new GridData(GridData.FILL_BOTH));
		parent.setLayout(new GridLayout());

		// Left panel
		Table table = new Table(parent, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL
				| SWT.V_SCROLL);
		table.setLayoutData(new GridData(GridData.FILL_BOTH));

		// 2) Initialize the table viewer + SWT Table
		TableViewer viewer = new TableViewer(table);
		viewer.setContentProvider(ArrayContentProvider.getInstance());
		viewer.setLabelProvider(new LabelProvider());

		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		// 3) Create Table columns with sort of paginated list.
		int pageSize = 10;
		final PageableController controller = new PageableController(pageSize);
		final IPageLoader&lt;PageResult&gt; pageLoader = new PageResultLoaderList(
				items);
		controller.addPageChangedListener(PageLoaderStrategyHelper
				.createLoadPageAndReplaceItemsListener(controller, viewer,
						pageLoader, PageResultContentProvider.getInstance(),
						null));

		// Create navigation page links
		ResultAndNavigationPageLinksRenderer resultAndPageLinksDecorator = new ResultAndNavigationPageLinksRenderer(
				parent, SWT.NONE, controller);
		resultAndPageLinksDecorator.setLayoutData(new GridData(
				GridData.FILL_HORIZONTAL));

		createColumns(viewer, controller);
		// 3) Set current page to 0 to refresh the table

		controller.setCurrentPage(0);

		shell.setSize(350, 250);
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}

	private static void createColumns(final TableViewer viewer,
			PageableController controller) {

		// First column is for the first name
		TableViewerColumn col = createTableViewerColumn(viewer, &quot;Name&quot;, 150);
		col.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				String p = (String) element;
				return p;
			}
		});
		col.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				Person p = (Person) element;
				return p.getName();
			}
		});
		col.getColumn().addSelectionListener(
				new SortTableColumnSelectionListener(&quot;name&quot;, controller));

		// Second column is for the adress
		col = createTableViewerColumn(viewer, &quot;Adress&quot;, 150);
		col.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				Person p = (Person) element;
				Address address = p.getAddress();
				if (address == null) {
					return &quot;&quot;;
				}
				return address.getName();
			}
		});
		col.getColumn()
				.addSelectionListener(
						new SortTableColumnSelectionListener(&quot;address.name&quot;,
								controller));
	}

	private static List createList() {
		List names = new ArrayList();
		for (int i = 1; i &lt; 100; i++) {
			names.add(new Person(&amp;quot;Name &amp;quot; + i, i &lt; 25 ? &amp;quot;Adress &amp;quot;
					+ Math.random() : null));
		}
		return names;
	}

	private static TableViewerColumn createTableViewerColumn(
			TableViewer viewer, String title, int bound) {
		final TableViewerColumn viewerColumn = new TableViewerColumn(viewer,
				SWT.NONE);
		final TableColumn column = viewerColumn.getColumn();
		column.setText(title);
		column.setWidth(bound);
		column.setResizable(true);
		column.setMoveable(true);
		return viewerColumn;
	}

}</pre></p>
<h3>Pagination in Table with PageableTable</h3>
<p>You can simplify the previous code by using org.eclipse.nebula.widgets.pagination.table.<strong>PageableTable</strong>. This explanation is based on the sample org.eclipse.nebula.widgets.pagination.examples.table.<strong>OneRendererPaginationTableWithPageableTableExample</strong>.</p>
<p>Here the code which create the SWT Table, the Pagination controller, the TableViewer:</p>
<p><pre class="brush: java;">final PageableTable pageableTable = new PageableTable(shell, SWT.BORDER, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, pageSize, null,
ResultAndNavigationPageLinksRendererFactory.getFactory());
</pre></p>
<p>This code create the SWT Table, viewer and add on the bottom an instance of ResultAndNavigationPageLinksRenderer.</p>
<p>PageLoader must be set like this: </p>
<p><pre class="brush: java;">
pageableTable.setPageLoader(new PageResultLoaderList(items));
</pre></p>
<p>Here the full code : </p>
<p><pre class="brush: java;">package org.eclipse.nebula.widgets.pagination.example.table.renderers;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.nebula.widgets.pagination.PageableController;
import org.eclipse.nebula.widgets.pagination.collections.PageResultContentProvider;
import org.eclipse.nebula.widgets.pagination.collections.PageResultLoaderList;
import org.eclipse.nebula.widgets.pagination.example.model.Address;
import org.eclipse.nebula.widgets.pagination.example.model.Person;
import org.eclipse.nebula.widgets.pagination.renderers.navigation.ResultAndNavigationPageLinksRendererFactory;
import org.eclipse.nebula.widgets.pagination.table.PageableTable;
import org.eclipse.nebula.widgets.pagination.table.SortTableColumnSelectionListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

/**
 * This sample display a list of model {@link Person} in a SWT Table with
 * pagination banner displayed with Page Results+Page Links on the top of the
 * SWT Table. The 2 columns which display the list of {@link Person} can be
 * clicked to sort the paginated list.
 * 
 */
public class OneRendererPaginationTableWithPageableTableExample {

	public static void main(String[] args) {

		Display display = new Display();
		Shell shell = new Shell(display);
		GridLayout layout = new GridLayout(1, false);
		shell.setLayout(layout);

		final List items = createList();

		int pageSize = 10;
		final PageableTable pageableTable = new PageableTable(shell,
				SWT.BORDER, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL
						| SWT.V_SCROLL, pageSize,
				PageResultContentProvider.getInstance(), null,
				ResultAndNavigationPageLinksRendererFactory.getFactory());
		pageableTable.setLayoutData(new GridData(GridData.FILL_BOTH));
		pageableTable.setPageLoader(new PageResultLoaderList(items));

		// 2) Initialize the table viewer + SWT Table
		TableViewer viewer = pageableTable.getViewer();
		viewer.setContentProvider(ArrayContentProvider.getInstance());
		viewer.setLabelProvider(new LabelProvider());

		Table table = viewer.getTable();
		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		PageableController controller = pageableTable.getController();
		createColumns(viewer, controller);
		// 3) Set current page to 0 to refresh the table

		controller.setCurrentPage(0);

		shell.setSize(350, 250);
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}

	private static void createColumns(final TableViewer viewer,
			PageableController controller) {

		// First column is for the first name
		TableViewerColumn col = createTableViewerColumn(viewer, &quot;Name&quot;, 150);
		col.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				String p = (String) element;
				return p;
			}
		});
		col.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				Person p = (Person) element;
				return p.getName();
			}
		});
		col.getColumn().addSelectionListener(
				new SortTableColumnSelectionListener(&quot;name&quot;, controller));

		// Second column is for the adress
		col = createTableViewerColumn(viewer, &quot;Adress&quot;, 150);
		col.setLabelProvider(new ColumnLabelProvider() {
			@Override
			public String getText(Object element) {
				Person p = (Person) element;
				Address address = p.getAddress();
				if (address == null) {
					return &quot;&quot;;
				}
				return address.getName();
			}
		});
		col.getColumn()
				.addSelectionListener(
						new SortTableColumnSelectionListener(&quot;address.name&quot;,
								controller));
	}

	private static List createList() {
		List names = new ArrayList();
		for (int i = 1; i &lt; 100; i++) {
			names.add(new Person(&amp;quot;Name &amp;quot; + i, i &lt; 25 ? &amp;quot;Adress &amp;quot;
					+ Math.random() : null));
		}
		return names;
	}

	private static TableViewerColumn createTableViewerColumn(
			TableViewer viewer, String title, int bound) {
		final TableViewerColumn viewerColumn = new TableViewerColumn(viewer,
				SWT.NONE);
		final TableColumn column = viewerColumn.getColumn();
		column.setText(title);
		column.setWidth(bound);
		column.setResizable(true);
		column.setMoveable(true);
		return viewerColumn;
	}

}
</pre></p>
<h2 id="NebulaPaginationWithSpringData">Nebula Pagination API (with Spring Data)</h2>
<p>By default the pagination structure used in the page loader is org.eclipse.nebula.widgets.pagination.<strong>PageResult</strong>. But it&#8217;s possible to use <a href="http://www.springsource.org/spring-data">Spring Data</a> pagination structure org.springframework.data.domain.<strong>Page</strong> with Nebula Pagination. We do that in our <a href="http://xdocreport-rap.opensagres.cloudbees.net/xdocreport?startup=fr.opensagres.xdocreport.eclipse.ui.application">Eclipse RCP/RAP XDocReport</a>.<br />
:</p>
<p>Before explaining how to use Spring Data with Nebula Pagination, here some interesting information: </p>
<ul>
<li>No need to add Spring dependencies to use Spring Data pagination structure.
  </li>
<li>If you wish paginate :
<ul>
<li>list stored in memory, I suggest to use <a href="#SpringDataDomainCollections">Spring Data domain Collections</a>.
      </li>
<li>list stored  in database I suggest you to use Spring Data JPA or Spring Data JDBC Extensions.
      </li>
<li>If you don&#8217;t know Spring Data, I suggets you to study it. You can just write your repository (dao) interface with name convention to manage JPA or JDBC like manage pagination in for Person list:<br />
<pre class="brush: java;">Page finadAll(Pageable pagable)</pre><br />
 and that&#8217;s all!
      </li>
</ul>
</li>
</ul>
<h3>Why Spring Data?</h3>
<h4>Why org.springframework.data.domain-only?</h4>
<p>The big problem with <a href="http://www.springsource.org/spring-data/commons">Spring Data Core</a> is that it dependends to Spring Core, Spring AOP etc. That&#8217;s why we have created <strong>org.springframework.data.domain-only</strong> which contains only the source of org.springframework.data.domain with pagination structure : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_springdatadomainonly.png?w=600" /></p>
<p>We have intention to tell about this problem to Spring Data Team and see if those bundles could exist?</p>
<p>If you wish to manage JPA (like we have done with our XDocReport demo), Spring Data JPA is very helpfull. In this case no need to use org.springframework.data.domain-only because Spring Data JPA requires Spring Core, AOP etc. The only case where  org.springframework.data.domain-only is intersesting with JPA is when you have Eclipse RCP client (client side) which calls services with remoting which uses JPA (server side). The client side  doesn&#8217;t call directly JPA, so no need to have in the Target Platform the Spring Data Core.</p>
<h4 id="SpringDataDomainCollections">Why org.springframework.data.domain.collections?</h4>
<p>In a business application, pagination is done generally with list coming from database. But sometimes list could coming from java list stored in memory. This is the case for our XDocReport application wich works with DAO layer (Data Access Object) : </p>
<ul>
<li>with JPA (it&#8217;s our JPA DAO).
  </li>
<li>or with java list stored in memory (it&#8217;s our mock DAO).
  </li>
</ol>
<p>For our mock DAO, we need to create Spring Data Page structure coming from a Java list (and not from JPA). Spring Data manages JPA, JDBC but not Java list in memory. The  org.springframework.data.domain.collections is able to create Page implementation coming from Java list and Pageable pagination criteria like this : </p>
<p><pre class="brush: java;">List persons =...
Pageable pageable =...
Page paginatedPersons = PageListHelper.createPage(items, pageable)
</pre></p>
<h3>How to use Spring Data with Nebula Pagination?</h3>
<p>If you wish use Spring Data Page structure with Nebula Pagination you must add <strong>org.eclipse.nebula.widgets.pagination.springdata</strong> in your project and : </p>
<ul>
<li>use org.eclipse.nebula.widgets.pagination.springdata.<strong>SpringDataPageableController</strong> instead of using org.eclipse.nebula.widgets.pagination.<strong>PageableController</strong>.
  </li>
<li>use org.eclipse.nebula.widgets.pagination.springdata.<strong>SpringDataPageContentProvider.getInstance()</strong> instead of using org.eclipse.nebula.widgets.pagination.<strong>PageResultContentProvider.getInstance()</strong>.
  </li>
</ul>
<p>If you wish use pagination with Java list in memory (and not Spring Data JPA or Spring Data JDBC).</p>
<ul>
<li>use org.eclipse.nebula.widgets.pagination.springdata.<strong>SpringDataPageLoaderList</strong> instead of org.eclipse.nebula.widgets.pagination.collections.<strong>PageResultLoaderList</strong>.
  </li>
</ul>
<h3>Pagination in Table at hand</h3>
<p>Here the &#8220;Pagination in Table at hand&#8221; with Spring Data (see org.eclipse.nebula.widgets.pagination.springdata.examples.renderer.OneRendererPaginationTableAtHandExample) : </p>
<p><pre class="brush: java;">final PageableController controller = new SpringDataPageableController(pageSize);
final IPageLoader pageLoader = new SpringDataPageLoaderList(items);
controller.addPageChangedListener(PageLoaderStrategyHelper.createLoadPageAndReplaceItemsListener(controller, viewer,pageLoader,	SpringDataPageContentProvider.getInstance(), null));</pre></p>
<h3>Pagination in Table with PageableTable</h3>
<p>Here the &#8220;Pagination in Table with PageableTable&#8221; with Spring Data (see org.eclipse.nebula.widgets.pagination.springdata.examples.renderer.OneRendererPaginationTableWithPageableTableExample) : </p>
<p><pre class="brush: java;">final PageableTable pageableTable = new PageableTable(shell,	SWT.BORDER, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL, pageSize, SpringDataPageContentProvider.getInstance(), null, ResultAndNavigationPageLinksRendererFactory.getFactory());
pageableTable.setLayoutData(new GridData(GridData.FILL_BOTH));
pageableTable.setPageLoader(new SpringDataPageLoaderList(items));
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/angelozerr.wordpress.com/5471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/angelozerr.wordpress.com/5471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/angelozerr.wordpress.com/5471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/angelozerr.wordpress.com/5471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/angelozerr.wordpress.com/5471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/angelozerr.wordpress.com/5471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/angelozerr.wordpress.com/5471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/angelozerr.wordpress.com/5471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/angelozerr.wordpress.com/5471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/angelozerr.wordpress.com/5471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/angelozerr.wordpress.com/5471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/angelozerr.wordpress.com/5471/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/angelozerr.wordpress.com/5471/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/angelozerr.wordpress.com/5471/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=5471&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://angelozerr.wordpress.com/2012/01/06/nebula_pagination/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c3176f508ba2f224d3b00dce0ca6c2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">akrogen</media:title>
		</media:content>

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_rapresumesearch1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_rcpresumesearch.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_graphicspageabletableexampleblue.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_graphicspageabletableexampleblack.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_graphicspageabletableexamplegreen.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_stringpageabletableexample.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_allrendererspageabletableexample.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_modelsortpageabletableexample.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_modelsortpageabletableworkinprocessexample1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_modelsortpageabletableworkinprocessexample2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_lazypagetableexample1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_lazypagetableexample2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_onerendererpaginationtableathandexample.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapagination_springdatadomainonly.png" medium="image" />
	</item>
		<item>
		<title>Eclipse Nebula Picture Control</title>
		<link>http://angelozerr.wordpress.com/2012/01/06/nebula_picture/</link>
		<comments>http://angelozerr.wordpress.com/2012/01/06/nebula_picture/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 15:49:58 +0000</pubDate>
		<dc:creator>angelozerr</dc:creator>
				<category><![CDATA[Eclipse Nebula]]></category>
		<category><![CDATA[Eclipse RAP]]></category>
		<category><![CDATA[Eclipse RCP]]></category>
		<category><![CDATA[Nebula Picture]]></category>

		<guid isPermaLink="false">http://angelozerr.wordpress.com/?p=5520</guid>
		<description><![CDATA[In some business application, your model (domain) contains sometimes image byte array (ex : photo for person model, logo for project model, etc). In our XDocReport project, we need to manage photo byte array with SWT control for the person model in our Eclipse RCP/RAP XDocReport, in the resume editor : This last screenshot is [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=5520&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In some business application, your model (domain) contains sometimes <strong>image byte array</strong> (ex : photo for person model, logo for project model, etc).  In our <a href="http://code.google.com/p/xdocreport/">XDocReport</a> project, we need to <strong>manage photo byte array with SWT control</strong> for the person model in our <a href="http://xdocreport-rap.opensagres.cloudbees.net/xdocreport?startup=fr.opensagres.xdocreport.eclipse.ui.application">Eclipse RCP/RAP XDocReport</a>, in the resume editor : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapicture_rapresumeeditor.png?w=600" /></p>
<p>This last screenshot is the resume editor in WEB context (Eclipse RAP). Here a screenshot in fat client context (Eclipse RCP) : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapicture_rcpresumeeditor.png?w=600" /></p>
<p>After several search, it seems that there is no project which provides a SWT picture control, which works with Eclipse RCP and RAP. So we decided to develop SWT <strong>PictureControl</strong> and give our code to <a href="http://eclipse.org/nebula/">Eclipse Nebula Project</a> with the <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365948">bug 365948</a>. Today Nebula Team are voting if the project will be accepted or not. </p>
<p><span id="more-5520"></span></p>
<h2>Plug-Ins</h2>
<p><strong>Nebula PictureControl</strong> contribution provides a <strong>SWT control to display an image, remove and modify it</strong>. It can be <strong>used in the RCP/RAP application context</strong>. This control is useful to manage photo, logo in a SWT, RCP and RAP Application. It works with SWT (use org.eclipse.nebula.widgets.picture.PictureControl) and FormToolkit (use org.eclipse.nebula.widgets.picture.FormPictureControl)</p>
<p>The PictureControl contribution zip contains : </p>
<ul>
<li><strong>org.eclipse.nebula.widgets.picture</strong> : plugin which contains the Nebula Picture control.
  </li>
<li><strong>org.eclipse.nebula.widgets.picture.example</strong> : Main example with PictureControl.
  </li>
</ul>
<h2>SimplePictureControl</h2>
<p>org.eclipse.nebula.widgets.picture.example.<strong>SimplePictureControl</strong> create a picture control like this : </p>
<p><pre class="brush: java;">PictureControl photoControl = new PictureControl(shell);</pre></p>
<p>If you Run org.eclipse.nebula.widgets.picture.example.<strong>SimplePictureControl</strong>, you will see that : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapicture_simplepicturecontrol.png?w=600" /></p>
<p>The <strong>&#8220;Modify&#8221; Link</strong> opens the file Explorer View to <strong>select an image</strong> : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapicture_simplepicturecontrol1.png?w=600" /></p>
<p>After selecting an image, the image appears : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapicture_simplepicturecontrol2.png?w=600" /></p>
<p>You can click in the <strong>&#8220;Delete&#8221; link</strong> to delete the image. It&#8217;s possible to get the image as byte array with the following code : </p>
<p><pre class="brush: java;">byte[] imageByteArray = photoControl.getImageByteArray();</pre></p>
<p>When image changes, the PictureControl stores the image as byte array and fires events to tell that image has changed. Here a sample code to observe the image changed :</p>
<p><pre class="brush: java;">photoControl.addPropertyChangeListener(PictureControl.IMAGE_BYTEARRAY_PROPERTY,
	new PropertyChangeListener() {
		public void propertyChange(PropertyChangeEvent event) {
			byte[] newImage = (byte[]) event.getNewValue();
		}
});</pre></p>
<p>This feature can be useful when you wish bind with <a href="http://wiki.eclipse.org/index.php/JFace_Data_Binding">JFace Databinding</a> the image byte array with a Model object. Here a sample to bind byte[] Person#getPhoto() : </p>
<p><pre class="brush: java;">
Person person=...;
IObservableValue uiValue = BeansObservables.observeValue(photoControl, PictureControl.IMAGE_BYTEARRAY_PROPERTY);
IObservableValue modelValue = PojoObservables.observeValue(person, &quot;photo&quot;);
bindingContext.bindValue(uiValue, modelValue, null, null);
</pre></p>
<h2>PictureControlWithDefaultImage</h2>
<p>It&#8217;s possible to set a default image (PictureControl#getImageByteArray() will return null in this case). If you run org.eclipse.nebula.widgets.picture.example.<strong>PictureControlWithDefaultImage</strong> you will see that : </p>
<p><img src="http://angelozerr.files.wordpress.com/2012/01/nebulapicture_picturecontrolwithdefaultimage.png?w=600" /></p>
<p>Here the code to set a default image : </p>
<p><pre class="brush: java;">Image defaultImage = new Image(display, PictureControlWithDefaultImage.class.getResourceAsStream(&quot;EmptyPhoto.jpg&quot;));
PictureControl photoControl = new PictureControl(shell);
photoControl.setDefaultImage(defaultImage);
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/angelozerr.wordpress.com/5520/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/angelozerr.wordpress.com/5520/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/angelozerr.wordpress.com/5520/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/angelozerr.wordpress.com/5520/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/angelozerr.wordpress.com/5520/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/angelozerr.wordpress.com/5520/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/angelozerr.wordpress.com/5520/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/angelozerr.wordpress.com/5520/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/angelozerr.wordpress.com/5520/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/angelozerr.wordpress.com/5520/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/angelozerr.wordpress.com/5520/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/angelozerr.wordpress.com/5520/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/angelozerr.wordpress.com/5520/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/angelozerr.wordpress.com/5520/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=5520&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://angelozerr.wordpress.com/2012/01/06/nebula_picture/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c3176f508ba2f224d3b00dce0ca6c2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">akrogen</media:title>
		</media:content>

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapicture_rapresumeeditor.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapicture_rcpresumeeditor.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapicture_simplepicturecontrol.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapicture_simplepicturecontrol1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapicture_simplepicturecontrol2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2012/01/nebulapicture_picturecontrolwithdefaultimage.png" medium="image" />
	</item>
		<item>
		<title>JAX-WS with Apache CXF and Eclipse [step2]</title>
		<link>http://angelozerr.wordpress.com/2011/08/24/jaxwscxf_step2/</link>
		<comments>http://angelozerr.wordpress.com/2011/08/24/jaxwscxf_step2/#comments</comments>
		<pubDate>Wed, 24 Aug 2011 15:59:42 +0000</pubDate>
		<dc:creator>angelozerr</dc:creator>
				<category><![CDATA[Apache CXF]]></category>
		<category><![CDATA[JAX-WS]]></category>

		<guid isPermaLink="false">http://angelozerr.wordpress.com/?p=5276</guid>
		<description><![CDATA[In [step1], we have configured CXF Eclipse Plugin to use CXF 2.4.2 and created an empty Dynamic Web project with Tomcat 7. In this article we will create a sample Java class HelloServiceImpl and publish it as WebService by using CXF Eclipse wizard. Basicly, this wizard will : modify the HelloServiceImpl to add well-formed JAX-WS [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=5276&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://angelozerr.wordpress.com/2011/08/23/jaxwscxf_step1/">[step1]</a>, we have <strong>configured CXF Eclipse Plugin to use CXF 2.4.2</strong> and created an <strong>empty Dynamic Web project</strong> with <strong>Tomcat 7</strong>.</p>
<p>In this article we will create a sample Java class <a href="#HelloServiceImpl">HelloServiceImpl</a> and <strong>publish it as WebService by using CXF Eclipse wizard</strong>. Basicly, this wizard will : </p>
<ul>
<li>modify the <a href="#WSHelloServiceImpl">HelloServiceImpl to add well-formed JAX-WS annotation.</a>
  </li>
<li>modify or create the Spring <a href="#beans.xml">beans.xml</a> file which declares the WebServices (in our case HelloServiceImpl) to publish.
  </li>
<li>modify the <a href="#web.xml">web.xml</a> to declare the <strong>Spring CXF Servlet</strong> used to dispatch to the proper WebService declared in the beans.xml.
  </li>
</ul>
<p><span id="more-5276"></span></p>
<h2>Download</h2>
<p>You can download <a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/cxf/step2/jaxwswithcxf_step2.zip">jaxwswithcxf_step2.zip</a> which is a zip which contains the Dynamic Web Project jaxwswithcxf with the HelloWorldImpl WebServices explained in this article.</p>
<h2 id="HelloServiceImpl">Create Class HelloServiceImpl</h2>
<p>Create in the jaxwswithcxf Dynamic Web Project the class <strong>org.sample.ws.HelloServiceImpl</strong> like this :  </p>
<p><pre class="brush: java;">package org.sample.ws;

public class HelloServiceImpl {

	public String getVersion() {
		return &quot;1.0&quot;;
	}

	public String hello(String user) {
		return &quot;Hello &quot; + user + &quot;!&quot;;
	}
}</pre></p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice1.png?w=600" /></p>
<h2 id="WSHelloServiceImpl">Create WebService HelloServiceImpl</h2>
<p>Web services can be created using two methods: </p>
<ul>
<li><strong>top-down development</strong> : Top-down Web services development involves creating a Web service from a <strong>WSDL file</strong>. WSDL file describes the services (methods, parameters) and defines the contract for the WebService. This WSDL file can also be used to generate the consumer of the WebService (which can be different technolgy (PHP, .Net, etc) than the WebService).
  </li>
<li><strong>bottom-up development</strong> : Bottom-up Web services development involves creating a Web service from a Java bean or enterprise bean.
  </li>
</ul>
<p>In our case we will use <strong>bottom-up development</strong> : we will use HelloServiceImpl Java class to create the Web Service.</p>
<h3 id="step1">step1 : select Java class</h3>
<p>Select HelloServiceImpl and click on the right mouse button to click on the <strong>Web Services/Create Web Service</strong> menu item : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice2.png?w=600" /></p>
<h3 id="step2">step2 : select CXF runtime</h3>
<p>This action opens the generic Wizard <strong>Web Service</strong> to generate WebService with Axis, Axis2, CXF, etc : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice3.png?w=600" /></p>
<p>In our case we want to generate CXF code. To do that, click on <strong>Web service runtime: Apache Axis</strong>, the <strong>Service Deployment Configuration</strong> opens. Select <strong>Apache CXF 2.x</strong> for Web service runtime : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice4.png?w=600" /></p>
<p>Click on OK button to close the <strong>Service Deployment Configuration</strong> dialog : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice5.png?w=600" /></p>
<p>You can notice that Web service runtime is <strong>Apache CXF 2.x</strong>. By default the <strong>Start service</strong> is selected which means as soon as wizard is finished, the server will start. I prefer to start my server manually, so I use <strong>Install Service</strong> to avoid launching the server at the end of the wizard : </p>
<h3 id="step3">step3 : Starting Point Configuration</h3>
<p>Click on <strong>Next</strong> button, the <strong>Starting Point Configuration</strong> wizard page displays. This page is used to generate an interface (for the HelloServiceImpl) annoted with JAX-WS annotation. In our case we change nothing and HelloServiceImpl will contain the JAX-WS annotation : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice6.png?w=600" /></p>
<h3 id="step4">step4 : Web Service JAX-WS Annotations Configuration</h3>
<p>Click on <strong>Next</strong> button, the <strong>Web Service JAX-WS Annotations Configuration</strong> wizard page displays. This page provides several checkbox that you can select/unselect to generate JAX-WS annotation. You can preview the generated code on the bottom of this page. In our case we don&#8217;t change the pre-defined values. We will play with those checkbox in a next article : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice7.png?w=600" /></p>
<h3 id="step5">step5 : Web Service Java2WS Configuration</h3>
<p>Click on <strong>Next</strong> button, the <strong>Web Service Java2WS Configuration</strong> wizard page displays. This wizard page provides some checkbox to select that you wish generate : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice8.png?w=600" /></p>
<ul>
<li><strong>Generate client</strong> generate simple client with JAX-WS Service.create()
  </li>
<li><strong>Generate server</strong> generate simple server of the WebService. This code starts a server (with Embedding Jetty) and publish the WebService by using JAX-WS Endpoint#publish.
  </li>
<li><strong>Generate Wrapper and Fault Beans</strong> generate Java class with JAXB annotation. Those classes are generated in the *.jaxws package (in our case org.sample.ws.jaxws). We will see the use of those classes in the next articles.
  </li>
<li><strong>Generate WSDL</strong> generate WSDL of the WebService.
<ul>
<li><strong>WSDL file</strong> : name of the WSDL file to generate.
      </li>
<li><strong>Default SOAP binding</strong>.
      </li>
<li><strong>Generate seperate XSD for the types</strong> : if this option is selected, the generated WSDL file will not contain the XML Schema which declares the type of the structure used in the method parameters.
      </li>
</ul>
</li>
</ul>
<h3 id="step6">step6 : Web Service Publication</h3>
<p>Click on <strong>Next</strong> button, the <strong>Web Service Publication</strong> wizard page displays : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice9.png?w=600" /></p>
<p>Click on Finish button to generate JAX-WS WebService and CXF component (Spring beans and web.xml).</p>
<h2>Result of CXF Wizard</h2>
<p>After finishing the generation of the CXF wizard, your workspace looks like this : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice10.png?w=600" /></p>
<p>The wizard generate several things : </p>
<ul>
<li><strong>[1] HelloServiceImpl</strong> : modify the Java class <a href="#HelloServiceImpl_JAXWS">HelloServiceImpl with JAX-WS annotation</a> :<br />
<pre class="brush: java;">package org.sample.ws;

import javax.jws.WebService;

@WebService(targetNamespace = &quot;http://ws.sample.org/&quot;, portName = &quot;HelloServiceImplPort&quot;, serviceName = &quot;HelloServiceImplService&quot;)
public class HelloServiceImpl {

	public String getVersion() {
		return &quot;1.0&quot;;
	}

	public String hello(String user) {
		return &quot;Hello &quot; + user + &quot;!&quot;;
	}
}</pre></p>
<p>The JAX-WS javax.jws.<strong>WebService</strong> annotation is used to indicate that this class is a WebService.</p>
</li>
<li><strong>[2] generate some classes</strong> in the <strong>org.sample.ws.jaxws</strong> package. Those classes are generated because the <strong>Generate Wrapper and Fault Beans</strong> of the page <a href="#step5">Web Service Java2WS Configuration</a> was checked. At this step, those classes are not used.
  </li>
<li><strong>[3] CXF librarires</strong>. If you open this item you will see that the wizard use the whole JAR of the CXF distribution :
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice11.png?w=600" /></p>
<p>Don&#8217;t be afraid of the amount of JARs, CXF needs few JARs.
  </li>
<li id="beans.xml"><strong>[4] beans.xml</strong> : this Spring file is used to declare with Spring bean the Java class HelloServiceImpl which must be published as WebService :
<p><pre class="brush: xml;">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:jaxws=&quot;http://cxf.apache.org/jaxws&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd&quot;&gt;
	&lt;import resource=&quot;classpath:META-INF/cxf/cxf.xml&quot; /&gt;
	&lt;import resource=&quot;classpath:META-INF/cxf/cxf-extension-soap.xml&quot; /&gt;
	&lt;import resource=&quot;classpath:META-INF/cxf/cxf-servlet.xml&quot; /&gt;
	&lt;jaxws:endpoint xmlns:tns=&quot;http://ws.sample.org/&quot; id=&quot;helloservice&quot;
		implementor=&quot;org.sample.ws.HelloServiceImpl&quot; wsdlLocation=&quot;wsdl/helloserviceimpl.wsdl&quot;
		endpointName=&quot;tns:HelloServiceImplPort&quot; serviceName=&quot;tns:HelloServiceImplService&quot;
		address=&quot;/HelloServiceImplPort&quot;&gt;
		&lt;jaxws:features&gt;
			&lt;bean class=&quot;org.apache.cxf.feature.LoggingFeature&quot; /&gt;
		&lt;/jaxws:features&gt;
	&lt;/jaxws:endpoint&gt;
&lt;/beans&gt;</pre></p>
<ul>
<li>the following declaration :<br />
<pre class="brush: xml;">&lt;jaxws:endpoint ... implementor=&quot;org.sample.ws.HelloServiceImpl&quot; </pre><br />
is used to publish the HelloServiceImpl class.
  </li>
<li>the following declaration :<br />
<pre class="brush: xml;">&lt;jaxws:endpoint ... address=&quot;/HelloServiceImplPort&quot; </pre><br />
is used to set the path for the URL of HelloServiceImpl. In our case our service will be available at <a href="http://localhost:8080/jaxwswithcxf/services/HelloServiceImplPort">http://localhost:8080/jaxwswithcxf/services/HelloServiceImplPort</a>.
  </li>
<li>the following declaration :<br />
<pre class="brush: xml;">&lt;jaxws:endpoint ... wsdlLocation=&quot;wsdl/helloserviceimpl.wsdl&quot; 
</pre><br />
set the location of the WSDL. If you remove this wsdlLocation attribute, WSDL will be generated if you access it by the URL <a href="http://localhost:8080/jaxwswithcxf/services/HelloServiceImplPort?wsdl">http://localhost:8080/jaxwswithcxf/services/HelloServiceImplPort?wsdl</a>.
  </li>
</ul>
</li>
<li id="web.xml">[5] <strong>web.xml</strong> is modified to declare the CXF servlet based on Spring
<p><pre class="brush: xml;">&lt;servlet&gt;
  &lt;description&gt;Apache CXF Endpoint&lt;/description&gt;
  &lt;display-name&gt;cxf&lt;/display-name&gt;
  &lt;servlet-name&gt;cxf&lt;/servlet-name&gt;
  &lt;servlet-class&gt;org.apache.cxf.transport.servlet.CXFServlet&lt;/servlet-class&gt;
  &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
&lt;/servlet&gt;
</pre></p>
<p>available at <a href="http://localhost:8080/jaxwswithcxf/services/">http://localhost:8080/jaxwswithcxf/services/</a> :</p>
<p><pre class="brush: xml;">&lt;servlet-mapping&gt;
  &lt;servlet-name&gt;cxf&lt;/servlet-name&gt;
  &lt;url-pattern&gt;/services/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
</pre></p>
<p>This servlet is used to dispatch to the proper WebServices. To know the deployed WebServices, this servlet use the Spring ApplicationContext loaded from the beans.xml : </p>
<p><pre class="brush: xml;">
  &lt;context-param&gt;
    &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
    &lt;param-value&gt;WEB-INF/beans.xml&lt;/param-value&gt;
  &lt;/context-param&gt;

  &lt;listener&gt;
    &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
  &lt;/listener&gt;
</pre></p>
<p>Here is the full code of the web.xml  : </p>
<p><pre class="brush: xml;">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;web-app xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot; xmlns:web=&quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot; xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd&quot; id=&quot;WebApp_ID&quot; version=&quot;3.0&quot;&gt;
  &lt;display-name&gt;jaxwswithcxf&lt;/display-name&gt;
  &lt;welcome-file-list&gt;
    &lt;welcome-file&gt;index.html&lt;/welcome-file&gt;
    &lt;welcome-file&gt;index.htm&lt;/welcome-file&gt;
    &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;
    &lt;welcome-file&gt;default.html&lt;/welcome-file&gt;
    &lt;welcome-file&gt;default.htm&lt;/welcome-file&gt;
    &lt;welcome-file&gt;default.jsp&lt;/welcome-file&gt;
  &lt;/welcome-file-list&gt;
  &lt;servlet&gt;
    &lt;description&gt;Apache CXF Endpoint&lt;/description&gt;
    &lt;display-name&gt;cxf&lt;/display-name&gt;
    &lt;servlet-name&gt;cxf&lt;/servlet-name&gt;
    &lt;servlet-class&gt;org.apache.cxf.transport.servlet.CXFServlet&lt;/servlet-class&gt;
    &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
  &lt;/servlet&gt;
  &lt;servlet-mapping&gt;
    &lt;servlet-name&gt;cxf&lt;/servlet-name&gt;
    &lt;url-pattern&gt;/services/*&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  &lt;session-config&gt;
    &lt;session-timeout&gt;60&lt;/session-timeout&gt;
  &lt;/session-config&gt;
  &lt;context-param&gt;
    &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
    &lt;param-value&gt;WEB-INF/beans.xml&lt;/param-value&gt;
  &lt;/context-param&gt;
  &lt;listener&gt;
    &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
  &lt;/listener&gt;
&lt;/web-app&gt;</pre>
  </li>
<li>[6] <strong>helloserviceimpl_schema1.xsd</strong> : this XML Schema describes the structure used in the WebService. This file is generated because the <strong>Generate seperate XSD for the types</strong> checkbox of the page <a href="#step5">Web Service Java2WS Configuration</a> was checked. Here is the content of this file :
<p><pre class="brush: xml;">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;&lt;xs:schema xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:tns=&quot;http://ws.sample.org/&quot; elementFormDefault=&quot;unqualified&quot; targetNamespace=&quot;http://ws.sample.org/&quot; version=&quot;1.0&quot;&gt;
&lt;xs:element name=&quot;getVersion&quot; type=&quot;tns:getVersion&quot;/&gt;
&lt;xs:element name=&quot;getVersionResponse&quot; type=&quot;tns:getVersionResponse&quot;/&gt;
&lt;xs:element name=&quot;hello&quot; type=&quot;tns:hello&quot;/&gt;
&lt;xs:element name=&quot;helloResponse&quot; type=&quot;tns:helloResponse&quot;/&gt;
&lt;xs:complexType name=&quot;getVersion&quot;&gt;
    &lt;xs:sequence/&gt;
  &lt;/xs:complexType&gt;
&lt;xs:complexType name=&quot;getVersionResponse&quot;&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element minOccurs=&quot;0&quot; name=&quot;return&quot; type=&quot;xs:string&quot;/&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;
&lt;xs:complexType name=&quot;hello&quot;&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element minOccurs=&quot;0&quot; name=&quot;arg0&quot; type=&quot;xs:string&quot;/&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;
&lt;xs:complexType name=&quot;helloResponse&quot;&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element minOccurs=&quot;0&quot; name=&quot;return&quot; type=&quot;xs:string&quot;/&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;
&lt;/xs:schema&gt;</pre>
  </li>
<li><strong>[7] helloserviceimpl.wsdl</strong> : is the generated WSDL. This file is generated because the <strong>Generate WSDL</strong> checkbox of the page <a href="#step5">Web Service Java2WS Configuration</a> was checked. Here is the content of this file :<br />
<pre class="brush: xml;">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;wsdl:definitions name=&quot;HelloServiceImplService&quot; targetNamespace=&quot;http://ws.sample.org/&quot; xmlns:wsdl=&quot;http://schemas.xmlsoap.org/wsdl/&quot; xmlns:tns=&quot;http://ws.sample.org/&quot; xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:soap=&quot;http://schemas.xmlsoap.org/wsdl/soap/&quot;&gt;
  &lt;wsdl:types&gt;
&lt;schema xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;
&lt;import namespace=&quot;http://ws.sample.org/&quot; schemaLocation=&quot;helloserviceimpl_schema1.xsd&quot;/&gt;
&lt;/schema&gt;
  &lt;/wsdl:types&gt;
  &lt;wsdl:message name=&quot;hello&quot;&gt;
    &lt;wsdl:part name=&quot;parameters&quot; element=&quot;tns:hello&quot;&gt;
    &lt;/wsdl:part&gt;
  &lt;/wsdl:message&gt;
  &lt;wsdl:message name=&quot;getVersion&quot;&gt;
    &lt;wsdl:part name=&quot;parameters&quot; element=&quot;tns:getVersion&quot;&gt;
    &lt;/wsdl:part&gt;
  &lt;/wsdl:message&gt;
  &lt;wsdl:message name=&quot;helloResponse&quot;&gt;
    &lt;wsdl:part name=&quot;parameters&quot; element=&quot;tns:helloResponse&quot;&gt;
    &lt;/wsdl:part&gt;
  &lt;/wsdl:message&gt;
  &lt;wsdl:message name=&quot;getVersionResponse&quot;&gt;
    &lt;wsdl:part name=&quot;parameters&quot; element=&quot;tns:getVersionResponse&quot;&gt;
    &lt;/wsdl:part&gt;
  &lt;/wsdl:message&gt;
  &lt;wsdl:portType name=&quot;HelloServiceImpl&quot;&gt;
    &lt;wsdl:operation name=&quot;getVersion&quot;&gt;
      &lt;wsdl:input name=&quot;getVersion&quot; message=&quot;tns:getVersion&quot;&gt;
    &lt;/wsdl:input&gt;
      &lt;wsdl:output name=&quot;getVersionResponse&quot; message=&quot;tns:getVersionResponse&quot;&gt;
    &lt;/wsdl:output&gt;
    &lt;/wsdl:operation&gt;
    &lt;wsdl:operation name=&quot;hello&quot;&gt;
      &lt;wsdl:input name=&quot;hello&quot; message=&quot;tns:hello&quot;&gt;
    &lt;/wsdl:input&gt;
      &lt;wsdl:output name=&quot;helloResponse&quot; message=&quot;tns:helloResponse&quot;&gt;
    &lt;/wsdl:output&gt;
    &lt;/wsdl:operation&gt;
  &lt;/wsdl:portType&gt;
  &lt;wsdl:binding name=&quot;HelloServiceImplServiceSoapBinding&quot; type=&quot;tns:HelloServiceImpl&quot;&gt;
    &lt;soap:binding style=&quot;document&quot; transport=&quot;http://schemas.xmlsoap.org/soap/http&quot;/&gt;
    &lt;wsdl:operation name=&quot;getVersion&quot;&gt;
      &lt;soap:operation soapAction=&quot;&quot; style=&quot;document&quot;/&gt;
      &lt;wsdl:input name=&quot;getVersion&quot;&gt;
        &lt;soap:body use=&quot;literal&quot;/&gt;
      &lt;/wsdl:input&gt;
      &lt;wsdl:output name=&quot;getVersionResponse&quot;&gt;
        &lt;soap:body use=&quot;literal&quot;/&gt;
      &lt;/wsdl:output&gt;
    &lt;/wsdl:operation&gt;
    &lt;wsdl:operation name=&quot;hello&quot;&gt;
      &lt;soap:operation soapAction=&quot;&quot; style=&quot;document&quot;/&gt;
      &lt;wsdl:input name=&quot;hello&quot;&gt;
        &lt;soap:body use=&quot;literal&quot;/&gt;
      &lt;/wsdl:input&gt;
      &lt;wsdl:output name=&quot;helloResponse&quot;&gt;
        &lt;soap:body use=&quot;literal&quot;/&gt;
      &lt;/wsdl:output&gt;
    &lt;/wsdl:operation&gt;
  &lt;/wsdl:binding&gt;
  &lt;wsdl:service name=&quot;HelloServiceImplService&quot;&gt;
    &lt;wsdl:port name=&quot;HelloServiceImplPort&quot; binding=&quot;tns:HelloServiceImplServiceSoapBinding&quot;&gt;
      &lt;soap:address location=&quot;http://localhost:9090/HelloServiceImplPort&quot;/&gt;
    &lt;/wsdl:port&gt;
  &lt;/wsdl:service&gt;
&lt;/wsdl:definitions&gt;
</pre>
  </li>
</ul>
<p>You can notice that you have JAX-WS Web Services menu item which shows you information about Java classes which are annotated with JAX-WS : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice12.png?w=600" /></p>
<h2>Launch WEB Application</h2>
<p>At this step we don’t have any client (consumer of the HelloServiceImpl) but we can test it. </p>
<p>An important information is that our WebService is declared with the org.apache.cxf.feature.<strong>LoggingFeature</strong> : </p>
<p><pre class="brush: xml;"> 
&lt;jaxws:endpoint id=&quot;helloservice&quot;
		...&gt;
		&lt;jaxws:features&gt;
			&lt;bean class=&quot;org.apache.cxf.feature.LoggingFeature&quot; /&gt;
		&lt;/jaxws:features&gt;
	&lt;/jaxws:endpoint&gt;
</pre></p>
<p>This feature is very usefull because it gives you the capability to trace for instance the received SOAP message (IN) and the sent SOAP message (OUT). We will check that in the Eclipse Console View.</p>
<p><a href="http://angelozerr.wordpress.com/2011/08/23/jaxwscxf_step1#LaunchWEBApplication">Launch jaxwswithcxf</a> to publish our WebService. After the start of the Web Application, you can notice some interesting logs in the Eclipse Console View : </p>
<ul>
<li>you can notice that WEB-INF/beans.xml is loaded :
<p><pre class="brush: plain;">...
INFO: Loading XML bean definitions from ServletContext resource [/WEB-INF/beans.xml]
...
</pre></p>
<p>And check that HelloServiceImpl is published : </p>
<p><pre class="brush: plain;">...
INFO: Creating Service {http://ws.sample.org/}HelloServiceImplService from WSDL: wsdl/helloserviceimpl.wsdl
22 août 2011 17:16:13 org.apache.cxf.endpoint.ServerImpl initDestination
INFO: Setting the server's publish address to be /HelloServiceImplPort
...</pre></p>
<h3>URLs</h3>
<p>At this step we can play with different URLs</p>
<h4>CXF Services list</h4>
<p>If you go at <a href="http://localhost:8080/jaxwswithcxf/services">http://localhost:8080/jaxwswithcxf/services</a>, you can see the list of WebServices (and REST services)  : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfserviceslist.png?w=600" /></p>
<h4>WSDL</h4>
<p>If you click on the link </p>
<p>WSDL : <a href="http://localhost:8080/jaxwswithcxf/services/HelloServiceImplPort?wsdl">{http://ws.sample.org/}HelloServiceImplService</a> </p>
<p>you will see the WSDL : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_wsdlinfirefox.png?w=600" /></p>
<p>URL of the WSDL is <a href="http://localhost:8080/jaxwswithcxf/services/HelloServiceImplPort?wsdl">http://localhost:8080/jaxwswithcxf/services/HelloServiceImplPort?wsdl</a></p>
<p>If you go to the Eclipse Console View, you will see some logs (because we have LoggingFeatures) : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_wsdlinfirefox2.png?w=600" /></p>
<h4>getVersion method</h4>
<p>It&#8217;s possible to call our getVersion method with the following URL <a href="http://localhost:8080/jaxwswithcxf/services/HelloServiceImplPort/getVersion">http://localhost:8080/jaxwswithcxf/services/HelloServiceImplPort/getVersion</a> which returns the SOAP message : </p>
<p><pre class="brush: xml;">&lt;soap:Envelope xmlns:soap=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;
	&lt;soap:Body&gt;
		&lt;ns2:getVersionResponse xmlns:ns2=&quot;http://ws.sample.org/&quot;&gt;
			&lt;return&gt;1.0&lt;/return&gt;
		&lt;/ns2:getVersionResponse&gt;
	&lt;/soap:Body&gt;
&lt;/soap:Envelope&gt;
</pre></p>
<p>If you go to the Eclipse Console View, you will see some logs (because we have LoggingFeatures)</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfgetversionlog.png?w=600" /></p>
<p>With this log you can see for instance the sent SOAP Message : </p>
<h4>hello method</h4>
<p>It&#8217;s possible to call method with parameter. If you call hello like this, you will that  : </p>
<p><a href="http://localhost:8080/jaxwswithcxf/services/HelloServiceImplPort/hello">http://localhost:8080/jaxwswithcxf/services/HelloServiceImplPort/hello</a></p>
<p><pre class="brush: xml;">&lt;soap:Envelope xmlns:soap=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;
	&lt;soap:Body&gt;
		&lt;ns2:helloResponse xmlns:ns2=&quot;http://ws.sample.org/&quot;&gt;
			&lt;return&gt;Hello null!&lt;/return&gt;
		&lt;/ns2:helloResponse&gt;
	&lt;/soap:Body&gt;
&lt;/soap:Envelope&gt;
</pre></p>
<p><pre class="brush: plain;">Hello null!</pre> is returned because we have not filled the parameter.</p>
<p>To set a parameter, you must access to this URL :<br />
<a href="http://localhost:8080/jaxwswithcxf/services/HelloServiceImplPort/hello?arg0=world">http://localhost:8080/jaxwswithcxf/services/HelloServiceImplPort/hello?arg0=world</a></p>
<p>This URL will return the following SOAP message : </p>
<p><pre class="brush: xml;">&lt;soap:Envelope xmlns:soap=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;
	&lt;soap:Body&gt;
		&lt;ns2:helloResponse xmlns:ns2=&quot;http://ws.sample.org/&quot;&gt;
			&lt;return&gt;Hello world!&lt;/return&gt;
		&lt;/ns2:helloResponse&gt;
	&lt;/soap:Body&gt;
&lt;/soap:Envelope&gt;</pre></p>
<p>Why <strong>arg0</strong>? Because if you check the XML Schema you have : </p>
<p><pre class="brush: xml;">&lt;xs:complexType name=&quot;hello&quot;&gt;
    &lt;xs:sequence&gt;
      &lt;xs:element minOccurs=&quot;0&quot; name=&quot;arg0&quot; type=&quot;xs:string&quot;/&gt;
    &lt;/xs:sequence&gt;
  &lt;/xs:complexType&gt;</pre></p>
<h2>Conclusion</h2>
<p>In this article we have <strong>generated with CXF Eclipse wizard a WebService with JAX-WS.</strong> This wizard initializes CXF by creating beans.xml wich declare Java classes which must be published and CXF Servlet. You can notice that HelloServiceImpl is not linked to CXF and could be used with another JAX-WS implementation.</p>
<p>In next article [step3] we will <strong>create and generate a client with JAX-WS</strong> (and CXF) which will consume our WebService.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/angelozerr.wordpress.com/5276/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/angelozerr.wordpress.com/5276/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/angelozerr.wordpress.com/5276/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/angelozerr.wordpress.com/5276/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/angelozerr.wordpress.com/5276/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/angelozerr.wordpress.com/5276/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/angelozerr.wordpress.com/5276/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/angelozerr.wordpress.com/5276/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/angelozerr.wordpress.com/5276/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/angelozerr.wordpress.com/5276/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/angelozerr.wordpress.com/5276/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/angelozerr.wordpress.com/5276/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/angelozerr.wordpress.com/5276/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/angelozerr.wordpress.com/5276/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=5276&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://angelozerr.wordpress.com/2011/08/24/jaxwscxf_step2/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c3176f508ba2f224d3b00dce0ca6c2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">akrogen</media:title>
		</media:content>

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice3.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice4.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice5.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice6.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice7.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice8.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice9.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice10.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice11.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_helloservice12.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfserviceslist.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_wsdlinfirefox.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_wsdlinfirefox2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfgetversionlog.png" medium="image" />
	</item>
		<item>
		<title>JAX-WS with Apache CXF and Eclipse [step1]</title>
		<link>http://angelozerr.wordpress.com/2011/08/23/jaxwscxf_step1/</link>
		<comments>http://angelozerr.wordpress.com/2011/08/23/jaxwscxf_step1/#comments</comments>
		<pubDate>Tue, 23 Aug 2011 13:36:36 +0000</pubDate>
		<dc:creator>angelozerr</dc:creator>
				<category><![CDATA[Apache CXF]]></category>
		<category><![CDATA[JAX-WS]]></category>

		<guid isPermaLink="false">http://angelozerr.wordpress.com/?p=5217</guid>
		<description><![CDATA[Few months ago, I had to migrate WebServices from my professional project based on Axis to JAX-WS which is the Java API for XML Web Services supported by the Java Platform, Standard Edition 6 (Java SE 6). There are several implementations of JAX-WS like : Glassfish &#8211; Metro. JBoss WS. Axis2. Spring JAX-WS. Apache CXF [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=5217&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Few months ago, I had to migrate WebServices from my professional project based on <a href="http://ws.apache.org/axis/java/">Axis</a> to <strong><a href="http://jax-ws.java.net/">JAX-WS</a></strong> which is the <strong>Java API for XML Web Services</strong> supported by the <a href="http://www.oracle.com/technetwork/java/javase/downloads/ea-jsp-142245.html">Java Platform, Standard Edition 6</a> (Java SE 6).  </p>
<p>There are several implementations of JAX-WS like : </p>
<ul>
<li><a href="http://metro.java.net/">Glassfish &#8211; Metro</a>.
  </li>
<li><a href="http://www.jboss.org/jbossws/">JBoss WS</a>.
  </li>
<li><a href="http://axis.apache.org/axis2/java/core/docs/jaxws-guide.html">Axis2</a>.
  </li>
<li><a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/remoting.html">Spring JAX-WS</a>.
  </li>
<li><a href="http://cxf.apache.org/">Apache CXF</a> which is based on <a href="http://xfire.codehaus.org/">XFire</a>.
  </li>
</ul>
<p>In my case, my professional project doesn&#8217;t use <a href="http://www.springsource.org/">Spring</a>. We have chosen <a href="http://cxf.apache.org/">Apache CXF</a> which <strong>use <a href="http://www.springsource.org/">Spring</a> by default</strong> but you can <strong>manage CXF without <a href="http://www.springsource.org/">Spring</a></strong>.</p>
<p>I have <strong>discovered and learned CXF with Eclipse JEE Indigo</strong> (works too with Eclipse JEE Helios) which <strong>provides Wizard to generate JAX-WS annotation and initialize CXF application</strong>. I think that playing with the CXF Eclipse Wizard is a good start point to learn CXF, so I decided to write some articles called <a href="http://angelozerr.wordpress.com/jaxwscxf/">JAX-WS with Apache CXF and Eclipse</a> (this link is the plan of articles) which explains step by step how to generate WebService and Consumer of WebService with CXF Eclipse Wizard.</p>
<p>In my articles I will use :</p>
<ul>
<li>the last version <strong>2.4.2</strong> of CXF.
  </li>
<li><strong>Tomcat 7</strong> as server.
  </li>
<li><strong>Eclipse JEE Indigo</strong>.
  </li>
</ul>
<p>But you can do the same thing with another version of CXF and another server. In this article I will explain how to </p>
<ol>
<li><a href="#InstallCXF">initialize the CXF Plugin</a>
  </li>
<li>and create an empty <a href="#InitializeCXFWebApplication">Eclipse Dynamic Web Project with Tomcat 7</a>.
  </li>
</ol>
<p><span id="more-5217"></span></p>
<h2>Download</h2>
<p>You can download <a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/cxf/step1/jaxwswithcxf_step1.zip">jaxwswithcxf_step1.zip</a> which is a zip which contains the empty Dynamic Web Project jaxwswithcxf.</p>
<h2>Why CXF?</h2>
<h3>My experimentation with Axis2</h3>
<p>When I started to play with JAX-WS, I decided to test <a href="http://axis.apache.org/axis2/java/core/docs/jaxws-guide.html">Axis2</a> because I was happy with <a href="http://ws.apache.org/axis/java/">Axis</a> but I was disappointed with the JAX-WS implementation of Axis2  for serveral reasons : </p>
<ul>
<li>documentation is very complex when you are a newbie.
  </li>
<li>axis2 distribution provides a lot of JARs and we don&#8217;t know which JARs we must select
  </li>
<li>default <a href="http://axis.apache.org/axis2/java/core/docs/jaxws-guide.html#DeployService">deploy service</a> force you to set your WebService JARs in a <strong>servicejars</strong> folder.
  </li>
<li>that&#8217;s why I tried to implement my own deployer to follow my custom architecure (WebService JARs are stored on another folders) but default axis2 deployer code is not based on JAX-WS <a href="http://download.oracle.com/javaee/5/api/javax/xml/ws/Endpoint.html#publish%28java.lang.String,%20java.lang.Object%29">Endpoint#publish(String address, Object implementor)</a> to deploy a WebService.
  </li>
<li>webservice is not a singleton
  </li>
<li>have some bugs with method which don&#8217;t have any parameter, etc.
  </li>
</ul>
<h3>My experimentation with CXF</h3>
<p>After my Axis2 experimentation, I have noticed that Eclipse JEE Indigo provides a <strong>wizard to generate JAX-WS annotation and initialize a Dynamic Web Project with CXF by using <a href="http://www.springsource.org/">Spring</a></strong>. Unfortunately we have not <a href="http://www.springsource.org/">Spring</a> in our project, but CXF can work without <a href="http://www.springsource.org/">Spring</a>! I will explain to you how to do that in the next articles.</p>
<p>Today I&#8217;m not disappointed in CXF for several reasons : </p>
<ul>
<li>Eclipse JEE Indigo generate well JJAX-WS annotation for the Java class you wish publish as WebService.
  </li>
<li>If you can use Spring, the CXF Wizard is very helpfull because it generate you the well web.xml with Spring CXF Servlet and Spring beans which are used to declare classes which must be published as WebService.
<p><a href="http://cxf.apache.org/docs/writing-a-service-with-spring.html">Writing a service with Spring</a> explains that.</p>
</li>
<li>If you don&#8217;t use Spring, you can still use the CXF Wizard to generate JAX-WS annotation. For the publish of the WebService you need to do that manually with Java code by using JAX-WS API <a href="http://download.oracle.com/javaee/5/api/javax/xml/ws/Endpoint.html#publish%28java.lang.String,%20java.lang.Object%29">Endpoint#publish(String address, Object implementor)</a> to deploy a WebService :
<p><pre class="brush: java;">MyService serviceInstance = new MyService();
Endpoint.publish(&quot;http://localhost:8080/MyService&quot;, serviceInstance);
</pre></p>
<p>will deploy your service available at the <a href="http://localhost:8080/MyService">http://localhost:8080/MyService</a>.</p>
<p><a href="http://cxf.apache.org/docs/a-simple-jax-ws-service.html">A simple JAX-WS service</a> explains that.</p>
<li>CXF architecture is based on <a href="http://cxf.apache.org/docs/interceptors.html">CXF Interceptors</a> (In/Out) to do some process before (In)/after (Out) calling your WebService. You can use existing CXF Interceptor or develop your own Interceptor to manage logging, security, etc.
  </li>
<li>CXF Team is very available. As soon as you post your questions/requirements on the CXF Mailing list, you have an answer.
  </li>
</ul>
<h2 id="InstallCXF">Install CXF</h2>
<p>CXF distribution provides several <a href="http://cxf.apache.org/docs/tools.html">tools</a> to generate JAX-WS annotation, WSDL, etc. The CXF Eclipse Plugin use those tools for the CXF wizard. </p>
<p>Installing CXF means : </p>
<ul>
<li><a href="#DownloadCXF">download CXF distribution</a>
  </li>
<li><a href="#InitializeCXFPlugin">Initialize CXF Eclipse Plugin</a> to set the path of the CXF distribution in the CXF Eclipse Preferences.
  </li>
</ul>
<h3 id="DownloadCXF">Download CXF distribution</h3>
<p>Go to the <a href="http://cxf.apache.org/download.html">CXF Download</a> and download the last version of the CXF distribution. In this article <strong>apache-cxf-2.4.2.zip</strong> is used : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfdownload1.png?w=600" /></p>
<p>Unzip <strong>apache-cxf-2.4.2.zip</strong> on your Hard Disk wherever you want. In my case I have unzipped to <strong>C:\Apache\apache-cxf-2.4.2</strong> : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfdownload2.png?w=600" /></p>
<h3 id="InitializeCXFPlugin">Initialize CXF Eclipse Plugin</h3>
<p>In this section we will set the path of the CXF distribution in the CXF Eclipse Preferences. Open your Eclipse JEE (Helios or Indigo) and go to the <strong>Window / Preferences</strong> menu : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfpereferenceseclipse1.png?w=600" /></p>
<p>This action opens the <strong>Preferences</strong> dialog. Click on the <strong>Web Services /  CXF 2.x Preferences</strong>  menu item : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfpereferenceseclipse2.png?w=600" /></p>
<p>Click on <strong>Add&#8230;</strong> button (on the right of the dialog) to select the path of the CXF distribution. This action opens the <strong>Add CXF Runtime</strong>. Add <strong>Browse&#8230;</strong> button and select the path of CXF distribution (in my case <strong>C:\Apache\apache-cxf-2.4.2</strong>) : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfpereferenceseclipse3.png?w=600" /></p>
<p>If the path of CXF distribution is valid, the fields of the dialog are filled automatically like this : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfpereferenceseclipse4.png?w=600" /></p>
<p>Click on <strong>Finish</strong> button, the dialog closes and CXF Runtime tab is filled with the CXF Runtime : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfpereferenceseclipse5.png?w=600" /></p>
<p>At this step, CXF Runtime is not available. Click on checkbox to make it available : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfpereferenceseclipse6.png?w=600" /></p>
<p>CXF Runtime is now available. In the next article we will see that CXF Runtime will be present in the generic WebServices wizard.</p>
<h2 id="InitializeCXFWebApplication">Initialize CXF Web Application</h2>
<p>Here we will create an empty <strong>Dynamic Web Project</strong> named <strong>jaxwswithcxf</strong> which will host the JAX-WS WebService.</p>
<h3 id="DownloadTomcat7">Download Tomcat 7</h3>
<p>Go to the <a href="http://tomcat.apache.org/download-70.cgi">Tomcat 7 Download</a> and download the last version of the Tomcat distribution. In this article <strong>apache-tomcat-7.0.20.zip</strong> is used : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_tomcat7download1.png?w=600" /></p>
<p>Unzip <strong>apache-tomcat-7.0.20.zip</strong> on your Hard Disk wherever you want. In my case I have unzipped to <strong>C:\Apache\apache-tomcat-7.0.20</strong> : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_tomcat7download2.png?w=600" /></p>
<h3 id="NewDynamicWebProject">Create Dynamic Web Project</h3>
<p>In this section we will create an empty <strong>jaxwswithcxf</strong> WEB application with <strong>Dynamic Web Project</strong>. To do that go to menu <strong>File/New /Dynamic Web Project</strong> : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_newdynamicwebproject1.png?w=600" /></p>
<p><strong>New Dynamic Web Project</strong> wizard opens. Fill in the project name with <strong>jaxwswithcxf</strong> and select <strong>Target runtime</strong> with your Server. If no server is defined, click on <strong>New Runtime&#8230;</strong> button to define it. </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_newdynamicwebproject2.png?w=600" /></p>
<h4 id="DefineNewServer">Define New Server</h4>
<p>Click on <strong>New Runtime&#8230;</strong> button, open the wizard to create a server. Select <strong>Tomcat v7.0 Server</strong> :  </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_newdynamicwebproject3.png?w=600" /></p>
<p>Click on Next button, the wizard page displays the selection of the Tomcat directory (existing Tomcat or empty folder where Tomcat must be installed). Here we will select the installed Tomcat 7. Click on the <strong>Browse&#8230;</strong> button to select the Tomcat home (in my case <strong>C:\Apache\apache-tomcat-7.0.20</strong>) : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_newdynamicwebproject4.png?w=600" /></p>
<h4>New Dynamic Web Project configurated</h4>
<p>Click on the <strong>Finish</strong> button, the <strong>New Dynamic Web Project</strong> wizard page appears : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_newdynamicwebproject5.png?w=600" /></p>
<p>Fields of this wizard are pre-filled like 3.0 Dynamic Module Web version which means that Tomcat 7.0 support 3.0 servlet (you can select another version if you wish). Click on Finish Button, the empty jaxwswithcxf WEB application is generated : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_initwebappworkspace.png?w=600" /></p>
<h2 id="LaunchWEBApplication">Launch Empty WEB application</h2>
<p>Now you can start the Tomcat server and launch the empty WEB Application. Select the jaxwswithcxf project, click on right mouse button and select menu <strong>Run As-&gt;Run on Server</strong> </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_launchwebappinitialized1.png?w=600" /></p>
<p>This action opens the wizard to select the server : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_launchwebappinitialized21.png?w=600" /></p>
<p>Select <strong>Tomcat 7.0 server</strong> and click on the <strong>Finish</strong> button. This action create a <strong>Server</strong> folder in your workspace which is the configuration of your Tomcat and launch the <strong>jaxwscxf</strong> WEB Application : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/cxf_launchwebappinitialized3.png?w=600" /></p>
<p>You can notice that you will have a 404 error because the generated web.xml is like this : </p>
<p><pre class="brush: xml;">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;web-app xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot; xmlns:web=&quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot; xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd&quot; id=&quot;WebApp_ID&quot; version=&quot;3.0&quot;&gt;
  &lt;display-name&gt;jaxwswithcxf&lt;/display-name&gt;
  &lt;welcome-file-list&gt;
    &lt;welcome-file&gt;index.html&lt;/welcome-file&gt;
    &lt;welcome-file&gt;index.htm&lt;/welcome-file&gt;
    &lt;welcome-file&gt;index.jsp&lt;/welcome-file&gt;
    &lt;welcome-file&gt;default.html&lt;/welcome-file&gt;
    &lt;welcome-file&gt;default.htm&lt;/welcome-file&gt;
    &lt;welcome-file&gt;default.jsp&lt;/welcome-file&gt;
  &lt;/welcome-file-list&gt;
&lt;/web-app&gt;</pre></p>
<p>And your web application contains no such files.</p>
<h2>Conclusion</h2>
<p>In this article we have initialized CXF Eclipse Plugin and created an empty Dynamic Web Project with Tomcat 7. </p>
<p>In the next article <a href="http://angelozerr.wordpress.com/2011/08/24/jaxwscxf_step2/">[step2]</a> we will <strong>create a simple Java class HelloServiceImpl</strong> and we will <strong>use CXF Eclipse wizard to expose it as WebService with JAX-WS and CXF</strong>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/angelozerr.wordpress.com/5217/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/angelozerr.wordpress.com/5217/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/angelozerr.wordpress.com/5217/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/angelozerr.wordpress.com/5217/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/angelozerr.wordpress.com/5217/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/angelozerr.wordpress.com/5217/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/angelozerr.wordpress.com/5217/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/angelozerr.wordpress.com/5217/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/angelozerr.wordpress.com/5217/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/angelozerr.wordpress.com/5217/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/angelozerr.wordpress.com/5217/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/angelozerr.wordpress.com/5217/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/angelozerr.wordpress.com/5217/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/angelozerr.wordpress.com/5217/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=5217&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://angelozerr.wordpress.com/2011/08/23/jaxwscxf_step1/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c3176f508ba2f224d3b00dce0ca6c2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">akrogen</media:title>
		</media:content>

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfdownload1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfdownload2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfpereferenceseclipse1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfpereferenceseclipse2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfpereferenceseclipse3.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfpereferenceseclipse4.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfpereferenceseclipse5.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_cxfpereferenceseclipse6.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_tomcat7download1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_tomcat7download2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_newdynamicwebproject1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_newdynamicwebproject2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_newdynamicwebproject3.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_newdynamicwebproject4.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_newdynamicwebproject5.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_initwebappworkspace.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_launchwebappinitialized1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_launchwebappinitialized21.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/cxf_launchwebappinitialized3.png" medium="image" />
	</item>
		<item>
		<title>My first steps with Eclipse RAP [step7]</title>
		<link>http://angelozerr.wordpress.com/2011/08/08/rap_step7/</link>
		<comments>http://angelozerr.wordpress.com/2011/08/08/rap_step7/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 15:43:33 +0000</pubDate>
		<dc:creator>angelozerr</dc:creator>
				<category><![CDATA[Eclipse RAP]]></category>
		<category><![CDATA[Eclipse RCP]]></category>

		<guid isPermaLink="false">http://angelozerr.wordpress.com/?p=4741</guid>
		<description><![CDATA[In [step6] we have seen how to manage UI with SWT Java code (no need to code Javascript). When I started &#8220;My first steps with Eclipse RAP&#8221; articles, I used Eclipse Helios which provides RAP 1.3. Since June 2011 Eclipse Indigo has been released and provides RAP (runtime and tooling) 1.4 which improves RAP. So, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=4741&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://angelozerr.wordpress.com/2011/05/31/rap_step6/">[step6]</a> we have seen how to manage UI with SWT Java code (no need to code Javascript). When I started &#8220;<a href="http://angelozerr.wordpress.com/about/rap/">My first steps with Eclipse RAP</a>&#8221; articles, I used <a href="http://www.eclipse.org/helios/">Eclipse Helios</a> which provides <a href="http://www.eclipse.org/rap/downloads/1.3/">RAP 1.3.</a> <strong>Since June 2011 <a href="http://www.eclipse.org/indigo/">Eclipse Indigo</a></strong> has been released and provides <strong><a href="http://www.eclipse.org/rap/downloads/1.4/">RAP (runtime and tooling) 1.4</a></strong> which improves <a href="http://www.eclipse.org/rap/">RAP</a>. So, I decided to start over my articles with <a href="http://www.eclipse.org/indigo/">Eclipse Indigo</a> to benefit from <a href="http://www.eclipse.org/rap/noteworthy/1.4/">New &amp; Noteworthy of RAP 1.4</a>. In this article we will : </p>
<ul>
<li>create an Eclipse RAP with PDE Template <a href="#RAPApplicationWithAView">&#8220;RAP Application with a view&#8221;</a> which generates this WEB Application :<br />
    <img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationstart2.png?w=600" />
  </li>
<li>create an Eclipse RCP with PDE Template <a href="#RCPApplicationWithAView">&#8220;RCP Application with a view&#8221;</a> which generates this Fat client Application :<br />
    <img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationstart2.png?w=600" />
  </li>
</ul>
<p>At the end of this article we will <a href="#comparison">compare the two generated RAP and RCP Application code</a> to see the differences between RCP and RAP Application. We will use this comparison in the [step8] to <strong>manage RAP (WEB Application) and RCP (Fat client) application with the same code</strong> (<strong>Single Sourcing</strong>).</p>
<p><span id="more-4741"></span></p>
<h2 id="prerequisite">Prerequisite</h2>
<p>Before starting this article, <a href="http://www.eclipse.org/downloads/">Download Eclipse for RCP and RAP Developers</a> distribution of <a href="http://www.eclipse.org/indigo/">Eclipse Indigo</a> to benefit from <a href="http://www.eclipse.org/rap/noteworthy/1.4/">New &amp; Noteworthy of RAP 1.4</a>.</p>
<h2 id="download">Download</h2>
<p>You can download <a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/rap/step7/rap_step7.zip">rap_step7.zip</a> which contains the following explained projects : </p>
<ul>
<li><strong>sample.application.rap</strong> which is the generated Eclipse <a href="#RAPApplicationWithAView">&#8220;RAP Application with a view&#8221;</a> explained in this article. To use this project you must unzip it and copy/paste in your Eclipse workspace. Import the Eclipse Plugin Project <strong>sample.application.rap</strong> with <strong>File/Import &#8230;</strong> menu. Go at <strong>General/Existing Projects Into Workspace </strong>and select <strong>sample.application.rap</strong>. This action will import the project in your workspace. It requires you to <a href="http://angelozerr.wordpress.com/2011/05/10/rap_step1/#InstallRAPTargetPlatform">install RAP Target Platform</a> to avoid compilation problems.
</li>
<li><strong>sample.application.rcp</strong> which is the generated Eclipse <a href="#RCPApplicationWithAView">&#8220;RCP Application with a view&#8221;</a> explained in this article. To use this project you must unzip it and copy/paste in your Eclipse workspace. Import the Eclipse Plugin Project <strong>sample.application.rcp</strong> with <strong>File/Import &#8230;</strong> menu. Go at <strong>General/Existing Projects Into Workspace </strong>and select <strong>sample.application.rcp</strong>. This action will import the project in your workspace. It requires you to use RCP Target Platform (by default if you create a new Workspace).</li>
</ul>
<h2 id="RAPApplicationWithAView">RAP Application with a view</h2>
<p>In this section we will generate a basic RAP application with a view with the PDE template <strong>RAP Application with a view</strong> with <strong><a href="http://www.eclipse.org/rap/downloads/1.4/">RAP 1.4</a></strong>. The new RAP tooling will install the RAP Target Platform.</p>
<h3 id="GenerateRAPApplication">Generate sample.application.rap</h3>
<p>RAP application is an Eclipse Plugin. To create a RAP Application we need to create an Eclipse Plugin. To do that, go to the <strong>File/New/Other&#8230;</strong> menu  : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard1.png?w=600" /></p>
<p>Select <strong>Plug-in Development/Plug-in Project</strong> node  : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard2.png?w=600" /></p>
<p>Click on <strong>Next</strong> button, the wizard page which gives the choice to create OSGi Bundle or Eclipse Plugin is displayed :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard3.png?w=600" /></p>
<ul>
<li>fill in the Project name field with <strong>sample.application.rap</strong>.</li>
<li>select the radio button <strong>Eclipse version</strong> because we would like to develop RAP application which is an Eclipse Plugin.</li>
</ul>
<p>Click on <strong>Next</strong> button, the wizard page which configures the Eclipse Plugin is displayed :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard4.png?w=600" /></p>
<ul>
<li><strong>ID</strong> field is the Bundle identifier (Bundle-SymbolicName: <strong>sample.application.rap</strong>).</li>
<li><strong>Version</strong> field is the Bundle version (Bundle-Version: <strong>1.0.0.qualifier</strong>).</li>
<li><strong>Name</strong> field is the Bundle name (Bundle-Name: <strong>RAP Application</strong>).
  </li>
<li><strong>Execution Environment</strong> sets the minimal version of the JRE in order to execute the bundle (Bundle-RequiredExecutionEnvironment: JavaSE-1.6).</li>
<li>you can unselect <strong>generate an activator, a Java class that controls the plug-in&#8217;s life cycle</strong> to avoid generating a Bundle Activator</li>
<li>select <strong>This plug-in will make contributions to the UI</strong> because we want to generate RAP application</li>
<li>select <strong>no</strong> for <strong>Would you like create a rich client application?</strong> because we want to generate a RAP application and not RCP application.</li>
</ul>
<p>Click on <strong>Next</strong> button, the wizard page which shows several PDE templates is displayed :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard5.png?w=600" /></p>
<p>Select <strong>RAP Application with a view</strong> template to generate RAP application with a view. When you select this template, you can notice on the right view a description of this PDE template &#8220;This code will need the <strong>RAP target</strong> to compile. At this step RAP target is not installed, but <a href="http://www.eclipse.org/rap/downloads/1.4/">RAP 1.4</a> Tooling will propose to install it at the end of this wizard.</p>
<p>Click on <strong>Next</strong> button, the wizard page which gives you the capability to customize package names, class names of the RAP project to generate is displayed :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard6.png?w=600" /></p>
<p>Don&#8217;t change default values and click on <strong>Finish</strong> Button to generate the RAP application. This action will generate the RAP Application but before the dialog box &#8220;Install RAP Target PLatform&#8221; is displayed : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard7.png?w=600" /></p>
<p>Click on <strong>OK</strong> button to install RAP Target Platform (in our case <a href="http://www.eclipse.org/rap/downloads/1.4/">RAP 1.4</a>). This action opens a dialog box to download and install the RAP Target Platform : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard8.png?w=600" /></p>
<p>When generation is done, your workspace looks like this : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard91.png?w=600" /></p>
<h3 id="RAPTargetPlatform">RAP Target Platform</h3>
<p>If you go to the <strong>Window / Preferences</strong> menu  and <strong>Plug-in Development / Target Platform,</strong> you can check that RAP Target Platform is installed and selected for the workspace : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationraptargetplatform.png?w=600" /></p>
<h2 id="LaunchRAPApplication">Launch RAP Application</h2>
<p>In this section we can start the generated RAP Application. To do that open MANIFEST.MF and click on <strong>Overview</strong> tab.</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationstart11.png?w=600" /></p>
<p>Click on <strong>Launch a RAP Application</strong> link on <strong>Testing</strong> section. This action starts the RAP WEB application by starting <strong>Jetty server</strong> and open Browser view with the first home page of the WEB Application : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationstart2.png?w=600" /></p>
<h3 id="Jetty404Error">Jetty 404 error</h3>
<p>If you use Eclipse Browser, sometimes when you start the RAP Application, you can have a 404 error : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationstart3.png?w=600" /></p>
<p>Don&#8217;t panic with that, wait a moment and refresh the browser. This errors comes from when the Eclipse browser is refreshed before that RAP Application is started.</p>
<h3>Set Jetty Port</h3>
<p>In the last screen, RAP application is available with the URL :</p>
<p><a href="http://127.0.0.1:3828/view?startup=sample.application.rap.viewapp">http://127.0.0.1:3828/view?startup=sample.application.rap.viewapp</a> but each time you will restart your RAP application, port will change (ex : <a href="http://127.0.0.1:3829/view?startup=sample.application.rap.viewapp">http://127.0.0.1:3829/view?startup=sample.application.rap.viewapp</a>). To set a port go to the <strong>Run/Run Configurations&#8230;</strong> menu :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/04/myfirststepwithrap_fixjettyport1.png?w=600" /></p>
<p>Select the RAP Application launch, go to the <strong>Main</strong> tab and set the port value to <strong>8080</strong> in the <strong>Runtime Settings/Manual Port configuration</strong> : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationfixjettyport.png?w=600" /></p>
<p>Now your RAP application will be available every time with the URL <a href="http://127.0.0.1:8080/view?startup=sample.application.rap.viewapp">http://127.0.0.1:8080/view?startup=sample.application.rap.viewapp</a>. Next articles will use this URL.</p>
<h2>RAP Application &#8211; Code</h2>
<p>Here I will not explain each component (Java, plugin.xml, MANIFEST.MF&#8230;) of the generated RAP Application, because I have already done that in the <a href="http://angelozerr.wordpress.com/2011/05/24/rap_step5/">[step5]</a>. However, there are few differences that it&#8217;s interesting to explain : </p>
<ul>
<li>RAP 1.4 application can <strong><a href="#UseIApplication">use IApplication instead of IEntryPoint</a></strong>.
  </li>
<li>RAP 1.4 tooling generate <a href="#branding">branding</a> which manage theme (color&#8230;.) of the RAP Application.
  </li>
<li>generate <a href="#View">View class</a> : s we have chosen the PDE template which generates a view, the RAP Application generates a View class with SWT Table.
  </li>
</ul>
<h3 id="UseIApplication">IApplication instead of IEntryPoint</h3>
<p>Since RAP 1.4, RAP Application can define the main entry with org.eclipse.equinox.app.<strong>IApplication</strong> instead of using org.eclipse.rwt.lifecycle.<strong>IEntryPoint</strong> which is specific RAP interface. This feature is very interesting because RCP Application use too org.eclipse.equinox.app.<strong>IApplication</strong> and facilitate the Single sourcing.</p>
<h4>plugin.xml</h4>
<p>Instead of declaring the main entry with RAP entrypoint : </p>
<p><pre class="brush: xml;">&lt;extension
         point=&quot;org.eclipse.rap.ui.entrypoint&quot;&gt;
      &lt;entrypoint
            class=&quot;sample.application.rap.Application&quot;
            parameter=&quot;view&quot;
            id=&quot;sample.application.rap.Application&quot;&gt;
      &lt;/entrypoint&gt;
   &lt;/extension&gt;
</pre></p>
<p>the RAP Application which is based on RAP 1.4, declares the application like this : </p>
<p><pre class="brush: xml;">&lt;extension
      id=&quot;viewapp&quot;
      point=&quot;org.eclipse.core.runtime.applications&quot;&gt;
   &lt;application
         thread=&quot;main&quot;
         cardinality=&quot;singleton-global&quot;
         visible=&quot;true&quot;&gt;
      &lt;run
            class=&quot;sample.application.rap.Application&quot;&gt;
     &lt;/run&gt;
   &lt;/application&gt;
&lt;/extension&gt;

</pre></p>
<h4>Application</h4>
<p>The application declaration is based on the sample.application.rap.<strong>Application</strong> class which looks like this : </p>
<p><pre class="brush: java;">package sample.application.rap;

import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
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 IApplication {

	public Object start(IApplicationContext context) throws Exception {
		Display display = PlatformUI.createDisplay();
		WorkbenchAdvisor advisor = new ApplicationWorkbenchAdvisor();
		return PlatformUI.createAndRunWorkbench(display, advisor);
	}

	public void stop() {
		// Do nothing
	}
}</pre></p>
<h3 id="branding">Branding</h3>
<p>RAP Tooling 1.4 generates an extension point with branding. What is branding? If you look at the RAP Application you have a green color for the title of the RAP Application : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationbranding1.png?w=600" /></p>
<p>Here is the declaration of the branding : </p>
<p><pre class="brush: xml;">&lt;extension
      point=&quot;org.eclipse.rap.ui.branding&quot;&gt;
   &lt;branding
         servletName=&quot;view&quot;
         themeId=&quot;org.eclipse.rap.design.example.fancy.theme&quot;
         defaultEntrypointId=&quot;sample.application.rap.viewapp&quot;
         title=&quot;RAP Single View&quot;
         id=&quot;sample.application.rap.branding&quot;&gt;
    &lt;/branding&gt;
&lt;/extension&gt;</pre></p>
<h4>org.eclipse.rap.rwt.theme.Default</h4>
<p>You can select another branding if you wish. To know the available branding, use completion (Ctrl+Space)  in the plugin.xml : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationbranding2.png?w=600" /></p>
<p>If you select for instance <strong>org.eclipse.rap.rwt.theme.Default</strong> </p>
<p><pre class="brush: xml;">&lt;extension
      point=&quot;org.eclipse.rap.ui.branding&quot;&gt;
   &lt;branding
         servletName=&quot;view&quot;
         themeId=&quot;org.eclipse.rap.rwt.theme.Default&quot;
         defaultEntrypointId=&quot;sample.application.rap.viewapp&quot;
         title=&quot;RAP Single View&quot;
         id=&quot;sample.application.rap.branding&quot;&gt;
    &lt;/branding&gt;
&lt;/extension&gt;</pre></p>
<p>and you restart your RAP Application, the WEB application will look like this:</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationbranding3.png?w=600" /></p>
<h3 id="View">View</h3>
<p>The View class was generated to display Table with 3 items. Here is the generated code sample.application.rap.<strong>View</strong> class : </p>
<p><pre class="brush: java;">package sample.application.rap;

import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

public class View extends ViewPart {
	public static final String ID = &quot;sample.application.rap.view&quot;;

	private TableViewer viewer;

	/**
	 * The content provider class is responsible for providing objects to the
	 * view. It can wrap existing objects in adapters or simply return objects
	 * as-is. These objects may be sensitive to the current input of the view,
	 * or ignore it and always show the same content (like Task List, for
	 * example).
	 */
	class ViewContentProvider implements IStructuredContentProvider {
		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
		}

		public void dispose() {
		}

		public Object[] getElements(Object parent) {
			return new String[] { &quot;One&quot;, &quot;Two&quot;, &quot;Three&quot; };
		}
	}

	class ViewLabelProvider extends LabelProvider implements
			ITableLabelProvider {
		public String getColumnText(Object obj, int index) {
			return getText(obj);
		}

		public Image getColumnImage(Object obj, int index) {
			return getImage(obj);
		}

		public Image getImage(Object obj) {
			return PlatformUI.getWorkbench().getSharedImages()
					.getImage(ISharedImages.IMG_OBJ_ELEMENT);
		}
	}

	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	public void createPartControl(Composite parent) {
		int style = SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL;
		viewer = new TableViewer(parent, style);
		viewer.setContentProvider(new ViewContentProvider());
		viewer.setLabelProvider(new ViewLabelProvider());
		viewer.setInput(getViewSite());
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		viewer.getControl().setFocus();
	}
}</pre></p>
<p>This code shows you how to manage a list of items with Java code by using SWT Table and JFace content/label provider. </p>
<h1>RCP Application</h1>
<h2 id="RCPApplicationWithAView">RCP Application with a view</h2>
<p>In this section we will generate a basic RCP application with a view with the PDE template <strong>RCP Application with a view</strong>.</p>
<h3 id="RAPTargetPlatform">RAP Target Platform</h3>
<p>Open a new workspace where RAP Target Platform is not installed. If you go to the <strong>Window / Preferences</strong> menu  and <strong>Plug-in Development / Target Platform,</strong> you can check RCP Target Platform is installed and selected for the workspace : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationrcptargetplatform.png?w=600" /></p>
<h3 id="GenerateRCPApplication">Generate sample.application.rcp</h3>
<p>RCP application is an Eclipse Plugin. To create a RCP Application we need to create an Eclipse Plugin. To do that, go to the <strong>File/New/Other&#8230;</strong> menu  : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard1.png?w=600" /></p>
<p>Select <strong>Plug-in Development/Plug-in Project</strong> node  : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard2.png?w=600" /></p>
<p>Click on <strong>Next</strong> button, the wizard page which gives the choice to create OSGi Bundle or Eclipse Plugin is displayed :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationwizard2.png?w=600" /></p>
<ul>
<li>fill in the Project name field with <strong>sample.application.rcp</strong>.</li>
<li>select the radio button <strong>Eclipse version</strong> because we would like to develop RCP application which is an Eclipse Plugin.</li>
</ul>
<p>Click on <strong>Next</strong> button, the wizard page which configure the Eclipse Plugin is displayed :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationwizard3.png?w=600" /></p>
<ul>
<li><strong>ID</strong> field is the Bundle identifier (Bundle-SymbolicName: <strong>sample.application.rcp</strong>).</li>
<li><strong>Version</strong> field is the Bundle version (Bundle-Version: <strong>1.0.0.qualifier</strong>).</li>
<li><strong>Name</strong> field is the Bundle name (Bundle-Name: <strong>RCP Application</strong>).
  </li>
<li><strong>Execution Environment</strong> sets the minimal version of the JRE in order to execute the bundle (Bundle-RequiredExecutionEnvironment: JavaSE-1.6).</li>
<li>you can unselect <strong>generate an activator, a Java class that controls the plug-in&#8217;s life cycle</strong> to avoid generating a Bundle Activator</li>
<li>select <strong>This plug-in will make contributions to the UI</strong> because we want to generate RCP application</li>
<li>select <strong>yes</strong> for <strong>Would you like create a rich client application?</strong> because we want to generate a RCP application.</li>
</ul>
<p>Click on <strong>Next</strong> button, the wizard page which show several PDE templates is displayed :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationwizard4.png?w=600" /></p>
<p>Select <strong>RCP Application with a view</strong> template to generate RCP application with a view. </p>
<p>Click on <strong>Next</strong> button, the wizard page which gives you the capability to customize package names, class names of the RCP project to generate is displayed :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationwizard5.png?w=600" /></p>
<p>When generation is done, your workspace looks like this : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationwizard6.png?w=600" /></p>
<h2 id="LaunchRCPApplication">Launch RCP Application</h2>
<p>In this section we can start the generated RCP Application. To do that open MANIFEST.MF and click on <strong>Overview</strong> tab.</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationstart1.png?w=600" /></p>
<p>Click on <strong>Launch an Eclipse Application</strong> link on <strong>Testing</strong> section. This action starts the RCP fat client application : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationstart2.png?w=600" /></p>
<h2 id="comparison">Comparison between RAP and RCP Application with a view</h2>
<p>If you compare the generated code between the RAP and RCP Application with a view you can notice that the code is almost the same. The main difference between RAP/RCP Application (in our case) is the dependencies :</p>
<p>For RAP Application, we have RAP dependencies : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationmanifest.png?w=600" /></p>
<p><pre class="brush: plain;">Require-Bundle: org.eclipse.rap.ui
...
Import-Package: javax.servlet;version=&quot;2.4.0&quot;,
 javax.servlet.http;version=&quot;2.4.0&quot;</pre></p>
<p>For RCP Application we have RCP dependencies  : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationmanifest.png?w=600" /></p>
<p><pre class="brush: plain;">Require-Bundle: org.eclipse.core.runtime,
 org.eclipse.ui</pre></p>
<p>As we use RAP 1.4, there is no difference for the the main entry which use org.eclipse.equinox.app.<strong>IApplication</strong> instead of using org.eclipse.rwt.lifecycle.<strong>IEntryPoint</strong> which is a specific RAP interface. </p>
<h2>Conclusion</h2>
<p>In this article we have used <strong><a href="http://www.eclipse.org/rap/downloads/1.4/">RAP (runtime and tooling) 1.4</a></strong> to generate RAP Application with a view. We have generated a RCP Application with a view and we have compared it with RAP Application. The main difference between RAP Application/ RCP Application (for this case) is the dependencies (RAP/RCP dependencies) managed with MANIFEST.MF file. In [step8] we will explain how to <strong>manage RAP (WEB Application) and RCP (Fat client) application with the same code</strong>. This feature is called <strong>Single Sourcing</strong>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/angelozerr.wordpress.com/4741/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/angelozerr.wordpress.com/4741/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/angelozerr.wordpress.com/4741/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/angelozerr.wordpress.com/4741/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/angelozerr.wordpress.com/4741/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/angelozerr.wordpress.com/4741/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/angelozerr.wordpress.com/4741/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/angelozerr.wordpress.com/4741/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/angelozerr.wordpress.com/4741/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/angelozerr.wordpress.com/4741/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/angelozerr.wordpress.com/4741/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/angelozerr.wordpress.com/4741/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/angelozerr.wordpress.com/4741/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/angelozerr.wordpress.com/4741/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=4741&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://angelozerr.wordpress.com/2011/08/08/rap_step7/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c3176f508ba2f224d3b00dce0ca6c2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">akrogen</media:title>
		</media:content>

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationstart2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationstart2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard3.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard4.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard5.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard6.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard7.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard8.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard91.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationraptargetplatform.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationstart11.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationstart2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationstart3.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/04/myfirststepwithrap_fixjettyport1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationfixjettyport.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationbranding1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationbranding2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationbranding3.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationrcptargetplatform.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationwizard2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationwizard2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationwizard3.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationwizard4.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationwizard5.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationwizard6.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationstart1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationstart2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rapapplicationmanifest.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/08/myfirststepwithrap_rcpapplicationmanifest.png" medium="image" />
	</item>
		<item>
		<title>WebSockets with Embedding Jetty [step4]</title>
		<link>http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step4/</link>
		<comments>http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step4/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 15:05:23 +0000</pubDate>
		<dc:creator>angelozerr</dc:creator>
				<category><![CDATA[Jetty]]></category>
		<category><![CDATA[WebSockets]]></category>

		<guid isPermaLink="false">http://angelozerr.wordpress.com/?p=4962</guid>
		<description><![CDATA[In [step3] we have created Chat WebSocket on server side and start the Jetty server with a Java main by using Embedding Jetty. In this article we will create a chat WEB Application which hosts chat.html. The chat WEB Application will be started on the 8080 port with Tomcat 6 by using Eclipse WTP Adaptor. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=4962&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step3/">[step3]</a> we have created Chat WebSocket on server side and start the Jetty server with a Java main by using Embedding Jetty. </p>
<p>In this article we will create a chat WEB Application which hosts <a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/websockets_jetty/step2/chat.html">chat.html</a>. The <strong>chat WEB Application will be started on the 8080 port with Tomcat 6</strong> by using Eclipse WTP Adaptor. This WEB Application will use the javax.servlet.<strong>ServletContextListener</strong> <a href="#ChatServerServletContextListener">ChatServerServletContextListener</a> for LifecycleListener :</p>
<ol>
<li>when the <strong>WEB Application starts, the Embedding Jetty starts on the 8081 port</strong>. Chat WebSocket on server side will be available at <strong>ws://localhost:8081/</strong>.
  </li>
<li>when the <strong>WEB Application stops, the Embedding Jetty stops</strong>.
  </li>
</ol>
<p>Here a scheme which shows you the architecture of the chat application hosted by Tomcat Server (8080 port) and WebSocket managed with Jetty Server (8081 port) :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_chatwebsockettomcat6architecture1.png?w=600" /></p>
<p>This schema shows you that:</p>
<ul>
<li><strong>HTTP request will be used on the 8080 port</strong> (ex : display the chat.html) to use Tomcat Server which doesn&#8217;t support WebSocket.
  </li>
<li><strong>WebSocket request will be used on the 8081 port</strong> (ex : click on the &#8220;Join&#8221; button to join the chat) to use Jetty Server which supports WebSocket.
  </li>
</ul>
<p><span id="more-4962"></span></p>
<h2>Download</h2>
<p>You can download <a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/websockets_jetty/step4/chat-webapp.zip">chat-webapp.zip</a> which contains Eclipse WTP Dynamic Web Project <strong>chat-webapp</strong> which is a the chat WEB Application configured with Tomcat 6 for WTP Tomcat Adaptor explained in this article.</p>
<h2>Initialize WEB Application</h2>
<p>In this section we will create and initialize an Eclipse WTP Dynamic Web Project <strong>chat-webapp</strong> to add <a href="http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step3/ #downloadJettyWebSocketJArs">Jetty-WebSocket JARs</a>, <a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/websockets_jetty/step2/chat.html">chat.html</a> and <a href="http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step3/#ChatWebSocketHandler">ChatWebSocketHandler</a> : </p>
<ol>
<li>Create a WEB Application with Dynamic Web Project with name <strong>chat-webapp</strong>. In my case I have used WTP Tomcat Adaptor with Tomcat 6.
  </li>
<li>Copy <a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/websockets_jetty/step2/chat.html">chat.html</a> in the <strong>/WebContent</strong> folder of the WEB Application.
  </li>
<li>Copy <a href="http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step3/ #downloadJettyWebSocketJArs">Jetty-WebSocket JARs</a> in the <strong>/WEB-INF/lib</strong> folder without <strong>servlet-api-2.5.jar</strong> because Tomcat already defines this JAR.
  </li>
<li>Copy/Paste the <a href="http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step3/#ChatWebSocketHandler">ChatWebSocketHandler</a> in the WEB Application.
  </li>
</ol>
<p>Your workspace looks like this:</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_chatwebsockettomcat6workspace.png?w=600" /></p>
<h2>Create Listener</h2>
<p>In this section we will create an implementation of javax.servlet.ServletContextListener to start and stop Jetty Server when WEB Application starts and stops.</p>
<h3 id="ChatServerServletContextListener">ChatServerServletContextListener</h3>
<p>Create org.samples.websockets.embeddingjetty.<strong>ChatServerServletContextListener</strong> like this: </p>
<p><pre class="brush: java;">package org.samples.websockets.embeddingjetty;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;

/**
 * Application Lifecycle Listener implementation for start/stop Embedding Jetty
 * Server configured to manage Chat WebSocket with {@link ChatWebSocketHandler}.
 * 
 */
public class ChatServerServletContextListener implements ServletContextListener {

	private Server server = null;

	/**
	 * Start Embedding Jetty server when WEB Application is started.
	 * 
	 */
	public void contextInitialized(ServletContextEvent event) {
		try {
			// 1) Create a Jetty server with the 8091 port.
			this.server = new Server(8081);
			// 2) Register ChatWebSocketHandler in the Jetty server instance.
			ChatWebSocketHandler chatWebSocketHandler = new ChatWebSocketHandler();
			chatWebSocketHandler.setHandler(new DefaultHandler());
			server.setHandler(chatWebSocketHandler);
			// 2) Start the Jetty server.
			server.start();
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	/**
	 * Stop Embedding Jetty server when WEB Application is stopped.
	 */
	public void contextDestroyed(ServletContextEvent event) {
		if (server != null) {
			try {
				// stop the Jetty server.
				server.stop();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}
</pre></p>
<h3>web.xml</h3>
<p>Declare the <a href="#ChatServerServletContextListener">ChatServerServletContextListener</a> listener in the <strong>web.xml</strong> like this: </p>
<p><pre class="brush: xml;">&lt;listener&gt;
	&lt;listener-class&gt;org.samples.websockets.embeddingjetty.ChatServerServletContextListener&lt;/listener-class&gt;
&lt;/listener&gt;
</pre></p>
<p>Here the full <strong>web.xml</strong> :</p>
<p><pre class="brush: xml;">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;web-app xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot; xmlns:web=&quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
	xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
	id=&quot;WebApp_ID&quot; version=&quot;2.5&quot;&gt;
	&lt;display-name&gt;chat-webapp&lt;/display-name&gt;
	&lt;welcome-file-list&gt;
		&lt;welcome-file&gt;chat.html&lt;/welcome-file&gt;
	&lt;/welcome-file-list&gt;
	&lt;listener&gt;
		&lt;listener-class&gt;org.samples.websockets.embeddingjetty.ChatServerServletContextListener&lt;/listener-class&gt;
	&lt;/listener&gt;
&lt;/web-app&gt;</pre></p>
<p>Your workspace looks like this : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_chatwebsockettomcat6workspace2.png?w=600" /></p>
<h2>Play with chat application!</h2>
<p>Start Tomcat Server, open a <a href="www.google.com/chrome">Google Chrome</a> and go to the <a href="http://localhost:8080/chat-webapp/chat.html">http://localhost:8080/chat-webapp/chat.html</a> URL to <a href="http://angelozerr.wordpress.com/2011/07/25/websockets_jetty_step2/#WebSocketChatOverview">play with the chat application</a> : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_chatwebsockettomcat6overview.png?w=600" /></p>
<h2>Limitation with Embedding Jetty</h2>
<p>The <strong>Embedding Jetty is a simple solution to support WebSocket on server side for any Java server</strong>. The 2 requirements with this solution are :</p>
<ul>
<li>the <strong>Java server must support servlet 2.5</strong> API because Embedding Jetty needs this JAR.
 </li>
<li><strong>port of the Java Server and the Embedding Jetty must be different</strong> otherwise it will have a conflict.
 </li>
</ul>
<h3>Embedding Jetty problem with same port than Java Server</h3>
<p>Testing the second point (Embedding Jetty with same port of the Java Server) is very easy. After modifying the port of the Embedding Jetty of the <a href="#ChatServerServletContextListener">ChatServerServletContextListener</a> like this :</p>
<p><pre class="brush: java;">...
this.server = new Server(8080);
...
</pre></p>
<p>If you restart your Java Server (in my case Tomcat 6) and go to the <a href="http://localhost:8080/chat-webapp/chat.html">http://localhost:8080/chat-webapp/chat.html</a> URL, you will have 404 error : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_chatwebsockettomcat6sameportproblem.png?w=600" /></p>
<p>The 404 error is thrown by the Embedding Jetty Server. It means that Embedding Jetty Server overrides the Java Server Tomcat 6.</p>
<h3>Another problem with Embedding Jetty</h3>
<p>I had discussion with <a href="http://blogs.webtide.com/gregw/">Greg Wilkins</a> the creator of the Jetty-WebSocket about the Embedding Jetty to manage WebSockets like I have suggested you. He tell me that they are another problems. With a separate server you will get something that looks like :</p>
<p><pre class="brush: plain;">
         +---HTTP------&gt; Websphere -----&gt; Req/Resp Application code
        /                                              ^
       /                                               |
Browser                                             Some link
       \                                               |
        \                                              v
         +---Websocket-&gt; Jetty ---------&gt; Messaging Application code
-----------------------------------------------------------------------------------------
</pre></p>
<p>You also get problems that HTTP and websocket are going to different hosts, so it is hard to share cookies and other security issues. </p>
<h3>Jetty Proxy seems to be the solution?</h3>
<p>The solution who he has suggested me is to use Jetty Proxy. Using a proxy, you can make the Jetty server the main server for all connections, but have the application logic on the Java Server (Tomcat, WebShpere&#8230;) :</p>
<p><pre class="brush: plain;">
Browser====HTTP/Websocket=====&gt;Jetty----HTTP----&gt; Websphere ----&gt; Application
</pre></p>
<ul>
<li>Jetty would pass normal HTTP requests through to the Java Server (Tomcat, WebShpere&#8230;)  WEB Application.
  </li>
<li>Jetty would pass received WebSocket messages to the Java Server (Tomcat, WebShpere&#8230;)  WEB Application as HTTP requests.
  </li>
</ul>
<p>To send a WebSocket message, the WebSocket application would make a HTTP request to Jetty, which would then send the WebSocket message.</p>
<p>I have not studied Jetty Proxy but if I can do something, I will create a new article about that.</p>
<h2>Conclusion</h2>
<p>This article shows you that it&#8217;s easy to <strong>support WebSocket for any Java Server by using Embedding Jetty</strong>. However it exists some limitations like port problem, cookies and security that <a href="http://blogs.webtide.com/gregw/">Greg Wilkins</a> has explained. Jetty Proxy could be a solution but I have not studied that.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/angelozerr.wordpress.com/4962/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/angelozerr.wordpress.com/4962/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/angelozerr.wordpress.com/4962/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/angelozerr.wordpress.com/4962/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/angelozerr.wordpress.com/4962/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/angelozerr.wordpress.com/4962/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/angelozerr.wordpress.com/4962/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/angelozerr.wordpress.com/4962/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/angelozerr.wordpress.com/4962/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/angelozerr.wordpress.com/4962/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/angelozerr.wordpress.com/4962/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/angelozerr.wordpress.com/4962/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/angelozerr.wordpress.com/4962/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/angelozerr.wordpress.com/4962/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=4962&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step4/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c3176f508ba2f224d3b00dce0ca6c2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">akrogen</media:title>
		</media:content>

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_chatwebsockettomcat6architecture1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_chatwebsockettomcat6workspace.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_chatwebsockettomcat6workspace2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_chatwebsockettomcat6overview.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_chatwebsockettomcat6sameportproblem.png" medium="image" />
	</item>
		<item>
		<title>WebSockets with Embedding Jetty [step3]</title>
		<link>http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step3/</link>
		<comments>http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step3/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 09:45:38 +0000</pubDate>
		<dc:creator>angelozerr</dc:creator>
				<category><![CDATA[Jetty]]></category>
		<category><![CDATA[WebSockets]]></category>

		<guid isPermaLink="false">http://angelozerr.wordpress.com/?p=4755</guid>
		<description><![CDATA[In [step2] we have implemented our chat application on client side with JavasScript WebSocket component. In this article we will create chat WebSockets on server side with Jetty-WebSocket and start the Jetty Server with Embedding Jetty. We will create a Java main which start a Jetty Server and configure it to manage WebSockets Chat Application [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=4755&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://angelozerr.wordpress.com/2011/07/25/websockets_jetty_step2/">[step2]</a> we have implemented our chat application on client side with JavasScript <a href="http://dev.w3.org/html5/websockets/">WebSocket</a> component. In this article we will create chat WebSockets on server side with <a href="#Jetty-Websocket">Jetty-WebSocket</a> and start the Jetty Server with <a href="#EmbeddingJetty">Embedding Jetty</a>. We will create a Java main which <a href="#RegisterChatWebSocketHandler">start a Jetty Server and configure it to manage WebSockets Chat Application</a> on server side.</p>
<p>We will use Eclipse IDE to create a Java Project <strong>org.samples.websockets.embeddingjetty</strong> (but you can do with another IDE if you wish). At the end of this article our workspace will looks like this: </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_chatwebsocketworkspace.png?w=600" /></p>
<p><span id="more-4755"></span></p>
<h2>Download</h2>
<p>You can download several Eclipse projects explained in this article:</p>
<ul>
<li><a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/websockets_jetty/step3/org.samples.websockets.embeddingjetty_step3_1.zip">org.samples.websockets.embeddingjetty_step3_1.zip</a> contains Eclipse Project <strong>org.samples.websockets.embeddingjetty</strong> explained in <a href="#downloadJettyWebSocketJArs">this</a> section. This project is Java project with <strong>pom.xml</strong> and maven launch (for M2Eclipse) configure it to download Jetty-WebSocket JARs with maven.
  </li>
<li><a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/websockets_jetty/step3/org.samples.websockets.embeddingjetty_step3_2.zip">org.samples.websockets.embeddingjetty_step3_2.zip</a> contains Eclipse Project <strong>org.samples.websockets.embeddingjetty</strong> explained in <a href="#downloadJettyWebSocketJArs">this</a> section. This project is Java project with Jetty-WebSocket JARs stored in the <strong>lib</strong> folder.
  </li>
<li><a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/websockets_jetty/step3/org.samples.websockets.embeddingjetty_step3_3.zip">org.samples.websockets.embeddingjetty_step3_2.zip</a> contains Eclipse Project <strong>org.samples.websockets.embeddingjetty</strong> explained in <a href="#EmbeddingJetty">this</a> section. This project contains chat.html (client side) and chat application with Jetty-WebSocket on server side.
  </li>
</ul>
<h2 id="downloadJettyWebSocketJArs">Download Jetty-WebSockets JARs</h2>
<p>You can download <a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/websockets_jetty/step3/org.samples.websockets.embeddingjetty_step3_2.zip">org.samples.websockets.embeddingjetty_step3_2.zip</a> which contains Eclipse project explained in this section.</p>
<p>Before starting read this section, create an Eclipse Java Project <strong>org.samples.websockets.embeddingjetty</strong>.</p>
<p>Here we will use <strong>Jetty-WebSockets 7.4.4.v20110707</strong> which is the last stable Jetty release. This version is very important because WebSockets API has changed since the article <a href="http://blogs.webtide.com/gregw/entry/jetty_websocket_server">Jetty WebSocket Server</a>. I would like say too that <a href="http://wiki.eclipse.org/Jetty_WTP_Plugin/Jetty_WTP_Websocket_Wizard">WTP Jetty Websocket_Wizard</a> doesn&#8217;t generate well WebSockets code for the Jetty 7.4.</p>
<p>At first we need to download required Jetty-WebSockets JARs :  </p>
<ul>
<li><strong>jetty-continuation-7.4.4.v20110707.jar</strong></li>
<li><strong>jetty-http-7.4.4.v20110707.jar</strong></li>
<li><strong>jetty-io-7.4.4.v20110707.jar</strong></li>
<li><strong>jetty-server-7.4.4.v20110707.jar</strong></li>
<li><strong>jetty-util-7.4.4.v20110707.jar</strong></li>
<li><strong>jetty-websocket-7.4.4.v20110707.jar</strong></li>
<li><strong>servlet-api-2.5.jar</strong></li>
</ul>
<p>If you wish download thoses JARs you can : </p>
<ul>
<li>download the project <a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/websockets_jetty/step3/org.samples.websockets.embeddingjetty_step3_2.zip">org.samples.websockets.embeddingjetty_step3_2.zip</a> which contains required Jetty-Websockets JARs.
  </li>
<li>download at hand the required JARs at <a href="http://mvnrepository.com/artifact/org.eclipse.jetty">http://mvnrepository.com/artifact/org.eclipse.jetty</a>.
  </li>
<li>use <a href="#maven">maven</a>.</li>
</ul>
<h3 id="maven">Jetty-WebSockets POM (maven)</h3>
<p>If you don&#8217;t know maven or you don&#8217;t know how to use maven to download JARs and you can read French, please read <a href="http://angelozerr.wordpress.com/2010/01/29/rcp_springdm_step14">Conception d’un client Eclipse RCP et serveur OSGI avec Spring DM [step14]</a> where I explain how download JARs by using POM maven.</p>
<p>In your POM, you must declare the Maven repository of the Jetty Eclipse Repository like this : </p>
<p><pre class="brush: xml;">&lt;repository&gt;
  &lt;id&gt;org.eclipse.jetty&lt;/id&gt;
  &lt;name&gt;Jetty Eclipse Repository&lt;/name&gt;
  &lt;url&gt;http://mvnrepository.com/artifact/org.eclipse.jetty&lt;/url&gt;
&lt;/repository&gt;
</pre></p>
<p>After you must declare the jetty-websocket dependency like this : </p>
<p><pre class="brush: xml;">&lt;dependency&gt;
  &lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
  &lt;artifactId&gt;jetty-websocket&lt;/artifactId&gt;
  &lt;version&gt;7.4.4.v20110707&lt;/version&gt;
&lt;/dependency&gt;
</pre></p>
<p>Here the full POM that I have used to download Jetty-WebSocket JARs : </p>
<p><pre class="brush: xml;">&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
	xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;
	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
	&lt;groupId&gt;org.samples.websockets&lt;/groupId&gt;
	&lt;artifactId&gt;org.samples.websockets.embeddingjetty&lt;/artifactId&gt;
	&lt;packaging&gt;pom&lt;/packaging&gt;
	&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;

	&lt;build&gt;
		&lt;plugins&gt;
			&lt;plugin&gt;
				&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
				&lt;artifactId&gt;maven-dependency-plugin&lt;/artifactId&gt;
				&lt;version&gt;2.1&lt;/version&gt;
				&lt;executions&gt;
					&lt;execution&gt;
						&lt;id&gt;copy-dependencies&lt;/id&gt;
						&lt;phase&gt;process-resources&lt;/phase&gt;
						&lt;goals&gt;
							&lt;goal&gt;copy-dependencies&lt;/goal&gt;
						&lt;/goals&gt;
						&lt;configuration&gt;
							&lt;outputDirectory&gt;lib&lt;/outputDirectory&gt;
							&lt;overWriteReleases&gt;true&lt;/overWriteReleases&gt;
							&lt;overWriteSnapshots&gt;true&lt;/overWriteSnapshots&gt;
							&lt;overWriteIfNewer&gt;true&lt;/overWriteIfNewer&gt;
							&lt;excludeTypes&gt;libd&lt;/excludeTypes&gt;
						&lt;/configuration&gt;
					&lt;/execution&gt;
				&lt;/executions&gt;
			&lt;/plugin&gt;
		&lt;/plugins&gt;
	&lt;/build&gt;

	&lt;repositories&gt;

		&lt;!-- Jetty Eclipse Repository --&gt;
		&lt;repository&gt;
			&lt;id&gt;org.eclipse.jetty&lt;/id&gt;
			&lt;name&gt;Jetty Eclipse Repository&lt;/name&gt;
			&lt;url&gt;http://mvnrepository.com/artifact/org.eclipse.jetty&lt;/url&gt;
		&lt;/repository&gt;

	&lt;/repositories&gt;

	&lt;dependencies&gt;

		&lt;!-- Jetty WebSockets --&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
			&lt;artifactId&gt;jetty-websocket&lt;/artifactId&gt;
			&lt;version&gt;7.4.4.v20110707&lt;/version&gt;
		&lt;/dependency&gt;

	&lt;/dependencies&gt;

&lt;/project&gt;</pre></p>
<p>You can do :</p>
<p><pre class="brush: plain;">mvn process-resources</pre></p>
<p>Or use the launch org.samples.websockets.embeddingjetty\launch-mvn\<strong>Process-resources Jetty-Websockets.launch</strong> from the <a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/websockets_jetty/step3/org.samples.websockets.embeddingjetty_step3_2.zip">org.samples.websockets.embeddingjetty_step3_2.zip</a> : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/downloadjettywebsocketsm2eclipse_1.png?w=600" /></p>
<p>After refreshing the Eclipse project, lib folder must appears with Jetty-WebSockets JARs : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/downloadjettywebsocketsm2eclipse_2.png?w=600" /></p>
<p>Update your ClassPath with Jetty-WebSockets JARs : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/updateclasspath.png?w=600" /></p>
<h2 id="EmbeddingJetty">Simple Server with Embedding Jetty</h2>
<p>In this section we will create a simple <strong>Embedding Jetty</strong> Server which is started in the 8081 port. To do that create the Java class org.samples.websockets.embeddingjetty.<strong>ChatWebSocketServer</strong> like this :</p>
<p><pre class="brush: java;">package org.samples.websockets.embeddingjetty;

import org.eclipse.jetty.server.Server;

public class ChatWebSocketServer {

	public static void main(String[] args) {
		try {
			// 1) Create a Jetty server with the 8091 port.
			Server server = new Server(8081);
			// 2) Start the Jetty server.
			server.start();
			// Jetty  server is stopped when the Thread is interruped.
			server.join();
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}
}
</pre></p>
<p>We have created a simple <strong>Jetty Server with Java main</strong> started on <strong>8081</strong> port. You can notice that the code is very simple! To test our code, start the Java main <strong>ChatWebSocketServer</strong>. The Eclipse console must display some <strong>Jetty logs</strong> which shows you Jetty Server is <strong>started in the 8081 port</strong> : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_jettylogsinconsole.png?w=600" /></p>
<p>Open a <a href="www.google.com/chrome">Google Chrome</a> (or another WEB Browser) and go at <a href="http://localhost:8081">http://localhost:8081</a> : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_simpleurl.png?w=600" /></p>
<p>You will see <strong>404 error</strong> because the <strong>Jetty server has not defined HTML resources files, Servlet, Filter</strong>&#8230; If you are interested to do that, you can find  several samples with Embedding Jetty at <a href="http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk/example-jetty-embedded/">SVN example-jetty-embedded</a>.</p>
<h2 id="Jetty-Websocket">Chat Application with Jetty-WebSockets</h2>
<p>In this section we create a Jetty Handler to manage WebSocket with <a href="#ChatWebSocketHandler">ChatWebSocketHandler</a> and <a href="#RegisterChatWebSocketHandler">register it to the Jetty Server instance</a>.</p>
<h3>ChatWebSocketHandler</h3>
<p>In this section we create a Jetty Handler <strong>ChatWebSocketHandler</strong> to manage WebSocket.</p>
<h4>Implements WebSocketHandler</h4>
<p>Create org.samples.websockets.embeddingjetty.ChatWebSocketHandler like this : </p>
<p><pre class="brush: java;">package org.samples.websockets.embeddingjetty;

import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.websocket.WebSocketHandler;

public class ChatWebSocketHandler extends WebSocketHandler {

	public WebSocket doWebSocketConnect(HttpServletRequest request,
			String protocol) {
		return null;
	}
}</pre></p>
<p>When this handler <a href="#RegisterChatWebSocketHandler">will be registered in the Jetty Server instance</a> and user of chat application on client side will click on &#8220;Join&#8221; button, which call the JavaScript code : </p>
<p><pre class="brush: xml;">var location = &quot;ws://localhost:8081/&quot;
this._ws = new WebSocket(location);
</pre></p>
<p>The Jetty server will call :</p>
<p><pre class="brush: java;">ChatWebSocketHandler#doWebSocketConnect(HttpServletRequest request, String protocol)</pre></p>
<p>This method creates an instance of org.eclipse.jetty.websocket.<strong>WebSocket</strong>. The server side will store an instance of org.eclipse.jetty.websocket.<strong>WebSocket</strong> per JavasScript <a href="http://dev.w3.org/html5/websockets/">WebSocket</a> component (client side).</p>
<h4>Implements WebSocket.OnTextMessage</h4>
<p>At this step we must implement org.eclipse.jetty.websocket.<strong>WebSocket</strong> to return an instance of this class when <pre class="brush: java;">ChatWebSocketHandler#doWebSocketConnect(HttpServletRequest request, String protocol)</pre> is called.</p>
<h5>WebSocket interface before 7.4 version</h5>
<p>Before Jetty 7.4 version that we are using, Jetty WebSocket interface was defined like this: </p>
<p><pre class="brush: java;">package org.eclipse.jetty.websocket;

import java.io.IOException;

public interface WebSocket
{
    @Deprecated
    public final byte LENGTH_FRAME=(byte)0x80;
    @Deprecated
    public final byte SENTINEL_FRAME=(byte)0x00;

    public final static byte   OP_CONTINUATION = 0x00;
    public final static byte   OP_CLOSE = 0x01;
    public final static byte   OP_PING = 0x02;
    public final static byte   OP_PONG = 0x03;
    public final static byte   OP_TEXT = 0x04;
    public final static byte   OP_BINARY = 0x05;
    
    public final static int CLOSE_NORMAL=1000;
    public final static int CLOSE_SHUTDOWN=1001;
    public final static int CLOSE_PROTOCOL=1002;
    public final static int CLOSE_DATA=1003;
    public final static int CLOSE_LARGE=1004;
    
    void onConnect(Outbound outbound);
    void onMessage(byte opcode,String data);
    void onFragment(boolean more,byte opcode,byte[] data, int offset, int length);
    void onMessage(byte opcode,byte[] data, int offset, int length);
    void onDisconnect(); // TODO add code 
    
    public interface Outbound
    {
        void sendMessage(String data) throws IOException;
        void sendMessage(byte opcode,String data) throws IOException;
        void sendMessage(byte opcode,byte[] data, int offset, int length) throws IOException;
        void sendFragment(boolean more,byte opcode,byte[] data, int offset, int length) throws IOException;
        void disconnect();
        void disconnect(int code,String message);
        boolean isOpen();
    }
}</pre></p>
<p>When you wanted to implement Jetty-WebSocket you needed to implement several methods like <strong>WebSocket#sendMessage(byte opcode,byte[] data, int offset, int length)</strong> throws IOException which is the method to send binary data, although this method was never called. For instance in our chat application, only <strong>WebSocket#sendMessage(String data) throws IOException</strong> is used because chat application client send simple text. </p>
<h5>WebSocket interface 7.4 version</h5>
<p>Jetty 7.4 version has changed the WebSocket interface like this : </p>
<p><pre class="brush: java;">package org.eclipse.jetty.websocket;

import java.io.IOException;

/**
 * WebSocket Interface.
 * &lt;p&gt;
 * This interface provides the signature for a server-side end point of a websocket connection.
 * The Interface has several nested interfaces, for each type of message that may be received.
 */
public interface WebSocket
{   
    /**
     * Called when a new websocket connection is accepted.
     * @param connection The Connection object to use to send messages.
     */
    void onOpen(Connection connection);
    
    /**
     * Called when an established websocket connection closes
     * @param closeCode
     * @param message
     */
    void onClose(int closeCode, String message);

    /**
     * A nested WebSocket interface for receiving text messages
     */
    interface OnTextMessage extends WebSocket
    {
        /**
         * Called with a complete text message when all fragments have been received.
         * The maximum size of text message that may be aggregated from multiple frames is set with {@link Connection#setMaxTextMessageSize(int)}.
         * @param data The message
         */
        void onMessage(String data);
    }

    /**
     * A nested WebSocket interface for receiving binary messages
     */
    interface OnBinaryMessage extends WebSocket
    {
        /**
         * Called with a complete binary message when all fragments have been received.
         * The maximum size of binary message that may be aggregated from multiple frames is set with {@link Connection#setMaxBinaryMessageSize(int)}.
         * @param data
         * @param offset
         * @param length
         */
        void onMessage(byte[] data, int offset, int length);
    }
    
    /**
     * A nested WebSocket interface for receiving control messages
     */
    interface OnControl extends WebSocket
    {
        /** 
         * Called when a control message has been received.
         * @param controlCode
         * @param data
         * @param offset
         * @param length
         * @return true if this call has completely handled the control message and no further processing is needed.
         */
        boolean onControl(byte controlCode,byte[] data, int offset, int length);
    }
    
    /**
     * A nested WebSocket interface for receiving any websocket frame
     */
    interface OnFrame extends WebSocket
    {
        /**
         * Called when any websocket frame is received.
         * @param flags
         * @param opcode
         * @param data
         * @param offset
         * @param length
         * @return true if this call has completely handled the frame and no further processing is needed (including aggregation and/or message delivery)
         */
        boolean onFrame(byte flags,byte opcode,byte[] data, int offset, int length);
        
        void onHandshake(FrameConnection connection);
    }
    
    /**
     * A  Connection interface is passed to a WebSocket instance via the {@link WebSocket#onOpen(Connection)} to 
     * give the application access to the specifics of the current connection.   This includes methods 
     * for sending frames and messages as well as methods for interpreting the flags and opcodes of the connection.
     */
    public interface Connection
    {
        String getProtocol();
        void sendMessage(String data) throws IOException;
        void sendMessage(byte[] data, int offset, int length) throws IOException;
        void disconnect();
        boolean isOpen();

        /**
         * @param size size&lt;0 No aggregation of frames to messages, &gt;=0 max size of text frame aggregation buffer in characters
         */
        void setMaxTextMessageSize(int size);
        
        /**
         * @param size size&lt;0 no aggregation of binary frames, &gt;=0 size of binary frame aggregation buffer
         */
        void setMaxBinaryMessageSize(int size);
        
        /**
         * Size in characters of the maximum text message to be received
         * @return size &lt;0 No aggregation of frames to messages, &gt;=0 max size of text frame aggregation buffer in characters
         */
        int getMaxTextMessageSize();
        
        /**
         * Size in bytes of the maximum binary message to be received
         * @return size &lt;0 no aggregation of binary frames, &gt;=0 size of binary frame aggregation buffer
         */
        int getMaxBinaryMessageSize();
    }
    
    /**
     * Frame Level Connection
     * &lt;p&gt;The Connection interface at the level of sending/receiving frames rather than messages.
     *
     */
    public interface FrameConnection extends Connection
    {
        boolean isMessageComplete(byte flags);
        void close(int closeCode,String message);
        byte binaryOpcode();
        byte textOpcode();
        byte continuationOpcode();
        byte finMask();
        
        boolean isControl(byte opcode);
        boolean isText(byte opcode);
        boolean isBinary(byte opcode);
        boolean isContinuation(byte opcode);
        boolean isClose(byte opcode);
        boolean isPing(byte opcode);
        boolean isPong(byte opcode);
        
        void sendControl(byte control,byte[] data, int offset, int length) throws IOException;
        void sendFrame(byte flags,byte opcode,byte[] data, int offset, int length) throws IOException;
    }
    
}</pre></p>
<p>So now when you wish implement Jetty WebSocket you must choose the internal WebSocket interface that you wish implement. In our case text message is used for our chat application, so we will implement <strong>WebSocket.OnTextMessage</strong> : </p>
<p><pre class="brush: java;">
/**
 * A nested WebSocket interface for receiving text messages
*/
interface OnTextMessage extends WebSocket
{
    /**
     * Called with a complete text message when all fragments have been received.
     * The maximum size of text message that may be aggregated from multiple frames is set with {@link Connection#setMaxTextMessageSize(int)}.
     * @param data The message
     */
    void onMessage(String data);
}</pre></p>
<p>Here hyerarchy of the Jetty 7.4 WebSocket interface :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_jettywebsocketinterface.png?w=600" /></p>
<p>Modify org.samples.websockets.embeddingjetty.<strong>ChatWebSocketHandler</strong> like this : </p>
<p><pre class="brush: java;">package org.samples.websockets.embeddingjetty;

import javax.servlet.http.HttpServletRequest;

import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketHandler;

public class ChatWebSocketHandler extends WebSocketHandler {

	public WebSocket doWebSocketConnect(HttpServletRequest request,
			String protocol) {
		return new ChatWebSocket();
	}

	private class ChatWebSocket implements WebSocket.OnTextMessage {

		public void onOpen(Connection connection) {

		}

		public void onMessage(String data) {

		}

		public void onClose(int closeCode, String message) {

		}
	}
}</pre></p>
<h4>Implements ChatWebSocket</h4>
<p>At this step we must implement each methods of ChatWebSocket.To do that modify org.samples.websockets.embeddingjetty.<strong>ChatWebSocketHandler</strong> like this : </p>
<p><pre class="brush: java;">package org.samples.websockets.embeddingjetty;

import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.servlet.http.HttpServletRequest;

import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketHandler;

public class ChatWebSocketHandler extends WebSocketHandler {

	private final Set&lt;ChatWebSocket&gt; webSockets = new CopyOnWriteArraySet&lt;ChatWebSocket&gt;();

	public WebSocket doWebSocketConnect(HttpServletRequest request,
			String protocol) {
		return new ChatWebSocket();
	}

	private class ChatWebSocket implements WebSocket.OnTextMessage {

		private Connection connection;

		public void onOpen(Connection connection) {
			// Client (Browser) WebSockets has opened a connection.
			// 1) Store the opened connection
			this.connection = connection;
			// 2) Add ChatWebSocket in the global list of ChatWebSocket
			// instances
			// instance.
			webSockets.add(this);
		}

		public void onMessage(String data) {
			// Loop for each instance of ChatWebSocket to send message server to
			// each client WebSockets.
			try {
				for (ChatWebSocket webSocket : webSockets) {
					// send a message to the current client WebSocket.
					webSocket.connection.sendMessage(data);
				}
			} catch (IOException x) {
				// Error was detected, close the ChatWebSocket client side
				this.connection.disconnect();
			}

		}

		public void onClose(int closeCode, String message) {
			// Remove ChatWebSocket in the global list of ChatWebSocket
			// instance.
			webSockets.remove(this);
		}
	}
}</pre></p>
<h3 id="RegisterChatWebSocketHandler">Register ChatWebSocketHandler in the Jetty Server</h3>
<p>At this step ChatWebSocketHandler is created and we must register it to the Jetty server instance like this: </p>
<p><pre class="brush: java;">ChatWebSocketHandler chatWebSocketHandler = new ChatWebSocketHandler();
			chatWebSocketHandler.setHandler(new DefaultHandler());
			server.setHandler(chatWebSocketHandler);
</pre></p>
<p>Modify org.samples.websockets.embeddingjetty.<strong>ChatWebSocketServer</strong> like this :  </p>
<p><pre class="brush: java;">package org.samples.websockets.embeddingjetty;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;

public class ChatWebSocketServer {

	public static void main(String[] args) {
		try {
			// 1) Create a Jetty server with the 8091 port.
			Server server = new Server(8081);
			// 2) Register ChatWebSocketHandler in the Jetty server instance.
			ChatWebSocketHandler chatWebSocketHandler = new ChatWebSocketHandler();
			chatWebSocketHandler.setHandler(new DefaultHandler());
			server.setHandler(chatWebSocketHandler);
			// 2) Start the Jetty server.
			server.start();
			// Jetty server is stopped when the Thread is interruped.
			server.join();
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}
}
</pre></p>
<h2 id="play">Play with Chat Application!</h2>
<p>At this step you can <a href="http://angelozerr.wordpress.com/2011/07/25/websockets_jetty_step2/#WebSocketChatOverview">play with the chat application</a>. To do that start the Jetty Server and open <a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/websockets_jetty/step2/chat.html">chat.html</a> in <a href="www.google.com/chrome">Google Chrome</a>:</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketstep2.png?w=600" /></p>
<h2>Conclusion</h2>
<p>In this article we have seen how to develop Chat Application WebSockets on server side with Jetty-WebSocket. We are used an <strong>Embedding Jetty</strong> to start the Jetty server and configure it to <strong>support our Chat Application WebSockets</strong> with the <a href="#ChatWebSocketHandler">ChatWebSocketHandler</a> class. This class can be used in a Jetty server too. In the <a href="http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step4">[step4]</a> I see you how to use our Chat Jetty-WebSocket in another Java Server (Tomcat, WebShpere&#8230;) which doesn&#8217;t support WebSocket.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/angelozerr.wordpress.com/4755/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/angelozerr.wordpress.com/4755/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/angelozerr.wordpress.com/4755/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/angelozerr.wordpress.com/4755/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/angelozerr.wordpress.com/4755/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/angelozerr.wordpress.com/4755/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/angelozerr.wordpress.com/4755/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/angelozerr.wordpress.com/4755/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/angelozerr.wordpress.com/4755/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/angelozerr.wordpress.com/4755/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/angelozerr.wordpress.com/4755/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/angelozerr.wordpress.com/4755/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/angelozerr.wordpress.com/4755/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/angelozerr.wordpress.com/4755/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=4755&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step3/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c3176f508ba2f224d3b00dce0ca6c2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">akrogen</media:title>
		</media:content>

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_chatwebsocketworkspace.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/downloadjettywebsocketsm2eclipse_1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/downloadjettywebsocketsm2eclipse_2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/updateclasspath.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_jettylogsinconsole.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_simpleurl.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_jettywebsocketinterface.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketstep2.png" medium="image" />
	</item>
		<item>
		<title>WebSockets with Embedding Jetty [step2]</title>
		<link>http://angelozerr.wordpress.com/2011/07/25/websockets_jetty_step2/</link>
		<comments>http://angelozerr.wordpress.com/2011/07/25/websockets_jetty_step2/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 22:44:06 +0000</pubDate>
		<dc:creator>angelozerr</dc:creator>
				<category><![CDATA[Jetty]]></category>
		<category><![CDATA[WebSockets]]></category>

		<guid isPermaLink="false">http://angelozerr.wordpress.com/?p=4859</guid>
		<description><![CDATA[In [step1] we have seen how WebSockets could be used in a chat application and introduce WebSockets component on client/server side. In this article we will create chat application on client side with JavaScript WebSocket component. Google Chrome implements WebSocket so our chat application will be tested with this browser. Jetty distribution provides a sample [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=4859&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://angelozerr.wordpress.com/2011/07/23/websockets_jetty_step1/">[step1]</a> we have seen <strong>how WebSockets could be used in a chat application and introduce WebSockets component on client/server side</strong>.</p>
<p>In this article we will <strong>create chat application on client side with JavaScript</strong> <a href="http://dev.w3.org/html5/websockets/">WebSocket</a> component. <strong><a href="www.google.com/chrome">Google Chrome</a> implements <a href="http://dev.w3.org/html5/websockets/">WebSocket</a></strong> so our chat application will be tested with this browser. </p>
<p>Jetty distribution provides a sample with chat.html. This article will explain step by step <strong>how to create chat application on client side with <a href="#chat.html">chat.html</a></strong>. In the next article <a href="http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step3/">[step3]</a>, we will create a Jetty server which will start to the <strong>8081</strong> port. The Chat WebSocket server will be available at <strong>ws://localhost:8081</strong>. You can notice<br />
that URL is <strong>ws://localhost:8081/</strong> and not <strong>http://localhost:8081/</strong>. <strong>ws://</strong> is WebSocket protocol. For secured protocol (like https://), <strong>wss://</strong> must be used.</p>
<p>Once WebSockets will be finished on client side (explained in this article) and server side (explained  in <a href="http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step3/">[step3]</a>), chat application will look like this : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketstep2.png?w=600" /></p>
<p><span id="more-4859"></span></p>
<h2>Download</h2>
<p>You can display (and download) <a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/websockets_jetty/step2/chat.html">chat.html</a> explained in this article.</p>
<h2 id="WebSocketChatOverview">WebSocket Chat &#8211; Overview</h2>
<p>Before explaining step by step how to create our chat application with <a href="#chat.html">chat.html</a>, it&#8217;s interesting to see in action the chat features provided by Jetty distribution.</p>
<h3>Check WebSocket support</h3>
<p>The Jetty <strong>chat.html</strong> test if Web Browser supports JavaScript <a href="http://dev.w3.org/html5/websockets/">WebSocket</a> component. For instance if you will open <a href="#chat.html">chat.html</a> with FireFox you will see this alert : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview1.png?w=600" /></p>
<h3>Chat connection</h3>
<p>When you will open <a href="#chat.html">chat.html</a> with <a href="www.google.com/chrome">Google Chrome</a>, you will see that the chat application will display Username field and &#8220;Join&#8221; button :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview21.png?w=600" /></p>
<p>To start a chat, you must fill Username field with an User and click on &#8220;Join&#8221; button or press Enter : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview3.png?w=600" /></p>
<p>This action creates a JavaScript</strong> <a href="http://dev.w3.org/html5/websockets/">WebSocket</a> which connect to the server. &#8220;Username&#8221; label is changed with &#8220;Chat&#8221; label, &#8220;Join&#8221; button label is changed with &#8220;Send&#8221; and Chat area display the new User who has joined the chat : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview4.png?w=600" /></p>
<p>If you open a new chat application in new tab and you join the chat, you can see that : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview6.png?w=600" /></p>
<p>If you go the first chat application you will see that the second user has joined the chat : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview7.png?w=600" /></p>
<h3>Chat communication</h3>
<p>If the first user type &#8220;hello&#8221; and press Enter or click on &#8220;Send&#8221; button, message is sent :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview8.png?w=600" /></p>
<p>You can check that the first user has received &#8220;hello&#8221; message from him :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview9.png?w=600" /></p>
<p>You can check that the second user has received &#8220;hello&#8221; message from the first user :</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview10.png?w=600" /></p>
<h2>UI Chat Application</h2>
<p>At this step we create a <strong>chat.html</strong> file to create the UI chat application.</p>
<h3>UI Chat Application &#8211; HTML</h3>
<p>UI chat application is composed with 3 areas : </p>
<ul>
<li>an <strong>HTML div which contains messages</strong>. This div is identified with &#8220;chat&#8221; id.
  </li>
<li>an <strong>HTML div which displays Username field and &#8220;Join&#8221; button</strong>. This div is identified with &#8220;join&#8221; id. This div is displayed at first time. Once User is connected after joining the chat, this div is hidden.
  </li>
<li>an <strong>HTML div which displays Chat field and &#8220;Send&#8221; button</strong>. This div is identified with &#8220;joined&#8221; id. This div is hidden at first time. Once User is connected after joining the chat, this div is displayed.
  </li>
</ul>
<p>Create a <strong>chat.html</strong> file with this content : </p>
<p><pre class="brush: xml;">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;WebSocket Chat&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;div id=&quot;chat&quot;&gt;&lt;/div&gt;
	&lt;div id=&quot;input&quot;&gt;
		&lt;div id=&quot;join&quot;&gt;
			Username:&amp;nbsp;
			&lt;input id=&quot;username&quot; type=&quot;text&quot; /&gt;&lt;input id=&quot;joinB&quot;
				class=&quot;button&quot; type=&quot;submit&quot; name=&quot;join&quot; value=&quot;Join&quot; /&gt;
		&lt;/div&gt;
		&lt;div id=&quot;joined&quot; class=&quot;hidden&quot;&gt;
			Chat:&amp;nbsp;&lt;input id=&quot;phrase&quot; type=&quot;text&quot; /&gt; &lt;input id=&quot;sendB&quot;
				class=&quot;button&quot; type=&quot;submit&quot; name=&quot;join&quot; value=&quot;Send&quot; /&gt;
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></p>
<p>CSS <strong>hidden</strong> class will manage the hidden of the div when CSS styles will be added. If you open <strong>chat.html</strong> with <a href="www.google.com/chrome">Google Chrome</a>, you will see that : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_createchatui1.png?w=600" /></p>
<h3>UI Chat Application &#8211; CSS Styles</h3>
<p>Now you can style chat application by modifying <strong>chat.html</strong> like this : </p>
<p><pre class="brush: xml;">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;WebSocket Chat&lt;/title&gt;
&lt;style type='text/css'&gt;
div {
	border: 0px solid black;
}

div#chat {
	clear: both;
	width: 40em;
	height: 20ex;
	overflow: auto;
	background-color: #f0f0f0;
	padding: 4px;
	border: 1px solid black;
}

div#input {
	clear: both;
	width: 40em;
	padding: 4px;
	background-color: #e0e0e0;
	border: 1px solid black;
	border-top: 0px
}

input#phrase {
	width: 30em;
	background-color: #e0f0f0;
}

input#username {
	width: 14em;
	background-color: #e0f0f0;
}

div.hidden {
	display: none;
}

span.from {
	font-weight: bold;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;div id=&quot;chat&quot;&gt;&lt;/div&gt;
	&lt;div id=&quot;input&quot;&gt;
		&lt;div id=&quot;join&quot;&gt;
			Username:&amp;nbsp;
			&lt;input id=&quot;username&quot; type=&quot;text&quot; /&gt;&lt;input id=&quot;joinB&quot;
				class=&quot;button&quot; type=&quot;submit&quot; name=&quot;join&quot; value=&quot;Join&quot; /&gt;
		&lt;/div&gt;
		&lt;div id=&quot;joined&quot; class=&quot;hidden&quot;&gt;
			Chat:&amp;nbsp;&lt;input id=&quot;phrase&quot; type=&quot;text&quot; /&gt; &lt;input id=&quot;sendB&quot;
				class=&quot;button&quot; type=&quot;submit&quot; name=&quot;join&quot; value=&quot;Send&quot; /&gt;
		&lt;/div&gt;
	&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></p>
<p>If you open <strong>chat.html</strong> with <a href="www.google.com/chrome">Google Chrome</a>, you will see that : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_createchatui2.png?w=600" /></p>
<h2>Chat logic with JavaScript WebSocket</h2>
<p>At this step we can manage the logic of the chat application with JavaScript by using JavaScript <a href="http://dev.w3.org/html5/websockets/">WebSocket</a> component. The <a href="http://dev.w3.org/html5/websockets/#websocket">WebSocket interface</a> defines several methods : </p>
<p><pre class="brush: plain;">[Constructor(in DOMString url, in optional DOMString protocols),
 Constructor(in DOMString url, in optional DOMString[] protocols)]
interface WebSocket {
  readonly attribute DOMString url;

  // ready state
  const unsigned short CONNECTING = 0;
  const unsigned short OPEN = 1;
  const unsigned short CLOSING = 2;
  const unsigned short CLOSED = 3;
  readonly attribute unsigned short readyState;
  readonly attribute unsigned long bufferedAmount;

  // networking
           attribute Function? onopen;
           attribute Function? onerror;
           attribute Function? onclose;
  readonly attribute DOMString extensions;
  readonly attribute DOMString protocol;
  void close([Clamp] in optional unsigned short code, in optional DOMString reason);

  // messaging
           attribute Function? onmessage;
           attribute DOMString binaryType;
  void send(in DOMString data);
  void send(in ArrayBuffer data);
  void send(in Blob data);
};
WebSocket implements EventTarget;</pre></p>
<h3>Scripts before loading page.</h3>
<p>At this step, we define JavaScript functions which manages chat application with JavaScript <a href="http://dev.w3.org/html5/websockets/">WebSocket</a>. The Chat WebSocket server will be available at <strong>ws://localhost:8081</strong>. After the HTML content : </p>
<p><pre class="brush: xml;">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;WebSocket Chat&lt;/title&gt;
</pre></p>
<p>Add this script : </p>
<p><pre class="brush: xml;">
&lt;script type=&quot;text/javascript&quot;&gt;
	if (!window.WebSocket)
		alert(&quot;WebSocket not supported by this browser&quot;);

	function $() {
		return document.getElementById(arguments[0]);
	}
	function $F() {
		return document.getElementById(arguments[0]).value;
	}

	function getKeyCode(ev) {
		if (window.event)
			return window.event.keyCode;
		return ev.keyCode;
	}
	
	var room = {
		join : function(name) {
			this._username = name;
			//var location = document.location.toString().replace('http://',
			//		'ws://').replace('https://', 'wss://');
			var location = &quot;ws://localhost:8081/&quot;
			this._ws = new WebSocket(location);
			this._ws.onopen = this._onopen;
			this._ws.onmessage = this._onmessage;
			this._ws.onclose = this._onclose;
			this._ws.onerror = this._onerror;
		},

		chat : function(text) {
			if (text != null &amp;&amp; text.length &gt; 0)
				room._send(room._username, text);
		},

		_onopen : function() {			
			$('join').className = 'hidden';
			$('joined').className = '';
			$('phrase').focus();
			room._send(room._username, 'has joined!');
		},

		_onmessage : function(m) {
			if (m.data) {
				var c = m.data.indexOf(':');
				var from = m.data.substring(0, c).replace('&lt;', '&amp;lt;').replace(
						'&gt;', '&amp;gt;');
				var text = m.data.substring(c + 1).replace('&lt;', '&amp;lt;')
						.replace('&gt;', '&amp;gt;');

				var chat = $('chat');
				var spanFrom = document.createElement('span');
				spanFrom.className = 'from';
				spanFrom.innerHTML = from + ':&amp;nbsp;';
				var spanText = document.createElement('span');
				spanText.className = 'text';
				spanText.innerHTML = text;
				var lineBreak = document.createElement('br');
				chat.appendChild(spanFrom);
				chat.appendChild(spanText);
				chat.appendChild(lineBreak);
				chat.scrollTop = chat.scrollHeight - chat.clientHeight;
			}
		},

		_onclose : function(m) {
			this._ws = null;
			$('join').className = '';
			$('joined').className = 'hidden';
			$('username').focus();
			$('chat').innerHTML = '';
		},

		_onerror : function(e) {
			alert(e);
		},
		
		_send : function(user, message) {
			user = user.replace(':', '_');
			if (this._ws)
				this._ws.send(user + ':' + message);
		}
	};
&lt;/script&gt;
</pre></p>
<p>Here some explanation about this script : </p>
<ol>
<li>Before loading the page, we must check if WebSocket is supported by the Web Browser :<br />
<pre class="brush: xml;">if (!window.WebSocket)
  alert(&quot;WebSocket not supported by this browser&quot;);
</pre>
  </li>
<li><strong>room</strong> JavaScript variable (var room = {&#8230;}) is declared to <strong>define 2 methods</strong> :
<ol>
<li><strong>room.join(name)</strong> which is called when user clicks on &#8220;Join&#8221; button or types Enter in the username field. This method create a JavaScript</strong> <a href="http://dev.w3.org/html5/websockets/">WebSocket</a> with the URL <strong>ws://localhost:8081/</strong> :<br />
<pre class="brush: xml;">var location = &quot;ws://localhost:8081/&quot;
this._ws = new WebSocket(location);</pre><br />
You can notice that URL is <strong>ws://localhost:8081/</strong> and not <strong>http://localhost:8081/</strong>. <strong>ws://</strong> is WebSocket protocol. For secured protocol (like https://), <strong>wss://</strong> must be used. After WebSocket creation, <strong>room.join(name)</strong> defines a private function for each methods of WebSocket :<br />
<pre class="brush: xml;">this._ws.onopen = this._onopen;
this._ws.onmessage = this._onmessage;
this._ws.onclose = this._onclose;
this._ws.onerror = this._onerror;</pre><br />
Here description of each methods : </p>
<ul>
<li><strong>WebSocket#onopen</strong> is called once User is connected. This function hide the &#8216;join&#8217; div, display the &#8216;joined&#8217; div and send a message to tell that user has joined :<br />
<pre class="brush: xml;">_onopen : function() {			
  $('join').className = 'hidden';
  $('joined').className = '';
  $('phrase').focus();
  room._send(room._username, 'has joined!');
}</pre><br />
send message is done by calling <strong>room._send</strong> which sends a message with <strong>WebSocket#send(in DOMString data)</strong> like this :<br />
<pre class="brush: xml;">_send : function(user, message) {
	user = user.replace(':', '_');
	if (this._ws)
		this._ws.send(user + ':' + message);
}</pre>
          </li>
<li><strong>WebSocket#onmessage</strong> is called when message is received. This function add the received message in the &#8216;chat&#8217; div. :<br />
<pre class="brush: xml;">_onmessage : function(m) {
	if (m.data) {
		var c = m.data.indexOf(':');
		var from = m.data.substring(0, c).replace('&lt;', '&amp;lt;').replace('&gt;', '&amp;gt;');
		var text = m.data.substring(c + 1).replace('&lt;', '&amp;lt;').replace('&gt;', '&amp;gt;');

		var chat = $('chat');
		var spanFrom = document.createElement('span');
		spanFrom.className = 'from';
		spanFrom.innerHTML = from + ':&amp;nbsp;';
		var spanText = document.createElement('span');
		spanText.className = 'text';
		spanText.innerHTML = text;
		var lineBreak = document.createElement('br');
		chat.appendChild(spanFrom);
		chat.appendChild(spanText);
		chat.appendChild(lineBreak);
		chat.scrollTop = chat.scrollHeight - chat.clientHeight;
	}
}
</pre>
          </li>
<li><strong>WebSocket#onclose</strong> is called when WebSocket is closed. This function displays the &#8216;join&#8217; div and hides the &#8216;joined&#8217; div :<br />
<pre class="brush: xml;">_onclose : function(m) {
	this._ws = null;
	$('join').className = '';
	$('joined').className = 'hidden';
	$('username').focus();
	$('chat').innerHTML = '';
}</pre>
          </li>
</ul>
</li>
<li><strong>room.chat(text)</strong> which is called when user clicks on &#8220;Send&#8221; button or type Enter in the phrase field (available when user has joined the chat). This method sends the content of the &#8216;phrase&#8217; field with <strong>WebSocket#send(in DOMString data)</strong> like this :<br />
<pre class="brush: xml;">chat : function(text) {
	if (text != null &amp;&amp; text.length &gt; 0)
		room._send(room._username, text);
}</pre>
      </li>
</ol>
</li>
</ol>
<h3>Scripts after loading page.</h3>
<p>At this step room variable which defines <strong>room.join(name)</strong> which create WebSocket and room.chat(text) which use WebSocket to send message is finished. Now we can call this room variable in click event button (&#8220;Join&#8221; and &#8220;Send&#8221;) and Enter event of the fields (&#8220;username&#8221; and &#8220;phrase&#8221;). To add events to the UI widgets button and input fields, add this script after the creation of the UI (after the last HTML div) :</p>
<p><pre class="brush: xml;">&lt;script type=&quot;text/javascript&quot;&gt;	
		// 1) When user is NOT connected, 'join' div is displayed with Username input + Join button
		$('username').setAttribute('autocomplete', 'OFF');
		// Enter in the username field, opens Chat WebSockets
		$('username').onkeyup = function(ev) {
			var keyc = getKeyCode(ev);
			if (keyc == 13 || keyc == 10) {
				room.join($F('username'));
				return false;
			}
			return true;
		};
		// &quot;Join&quot; button click opens Chat WebSockets
		$('joinB').onclick = function(event) {
			room.join($F('username'));
			return false;
		};
		
		// 2) When user is connected, 'phrase' div is displayed with Chat input + Send button		
		$('phrase').setAttribute('autocomplete', 'OFF');
		// Enter in the 'phrase' field send the message
		$('phrase').onkeyup = function(ev) {
			var keyc = getKeyCode(ev);
			if (keyc == 13 || keyc == 10) {
				room.chat($F('phrase'));
				$('phrase').value = '';
				return false;
			}
			return true;
		};
		// &quot;Send&quot; button click send the message
		$('sendB').onclick = function(event) {
			room.chat($F('phrase'));
			$('phrase').value = '';
			return false;
		};
	&lt;/script&gt;</pre></p>
<p>This scripts is not very difficult to understand. It add events to the input fields and buttons to call the room.join(name) or room.chat(text).</p>
<h2 id="chat.html">chat.html</h2>
<p>Here the full code of the <strong>chat.html</strong> : </p>
<p><pre class="brush: xml;">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;WebSocket Chat&lt;/title&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
	if (!window.WebSocket)
		alert(&quot;WebSocket not supported by this browser&quot;);

	function $() {
		return document.getElementById(arguments[0]);
	}
	function $F() {
		return document.getElementById(arguments[0]).value;
	}

	function getKeyCode(ev) {
		if (window.event)
			return window.event.keyCode;
		return ev.keyCode;
	}
	
	var room = {
		join : function(name) {
			this._username = name;
			//var location = document.location.toString().replace('http://',
			//		'ws://').replace('https://', 'wss://');
			var location = &quot;ws://localhost:8081/&quot;
			this._ws = new WebSocket(location);
			this._ws.onopen = this._onopen;
			this._ws.onmessage = this._onmessage;
			this._ws.onclose = this._onclose;
			this._ws.onerror = this._onerror;
		},

		chat : function(text) {
			if (text != null &amp;&amp; text.length &gt; 0)
				room._send(room._username, text);
		},

		_onopen : function() {			
			$('join').className = 'hidden';
			$('joined').className = '';
			$('phrase').focus();
			room._send(room._username, 'has joined!');
		},

		_onmessage : function(m) {
			if (m.data) {
				var c = m.data.indexOf(':');
				var from = m.data.substring(0, c).replace('&lt;', '&amp;lt;').replace(
						'&gt;', '&amp;gt;');
				var text = m.data.substring(c + 1).replace('&lt;', '&amp;lt;')
						.replace('&gt;', '&amp;gt;');

				var chat = $('chat');
				var spanFrom = document.createElement('span');
				spanFrom.className = 'from';
				spanFrom.innerHTML = from + ':&amp;nbsp;';
				var spanText = document.createElement('span');
				spanText.className = 'text';
				spanText.innerHTML = text;
				var lineBreak = document.createElement('br');
				chat.appendChild(spanFrom);
				chat.appendChild(spanText);
				chat.appendChild(lineBreak);
				chat.scrollTop = chat.scrollHeight - chat.clientHeight;
			}
		},

		_onclose : function(m) {
			this._ws = null;
			$('join').className = '';
			$('joined').className = 'hidden';
			$('username').focus();
			$('chat').innerHTML = '';
		},

		_onerror : function(e) {
			alert(e);
		},
		
		_send : function(user, message) {
			user = user.replace(':', '_');
			if (this._ws)
				this._ws.send(user + ':' + message);
		}
	};
&lt;/script&gt;
&lt;style type='text/css'&gt;
div {
	border: 0px solid black;
}

div#chat {
	clear: both;
	width: 40em;
	height: 20ex;
	overflow: auto;
	background-color: #f0f0f0;
	padding: 4px;
	border: 1px solid black;
}

div#input {
	clear: both;
	width: 40em;
	padding: 4px;
	background-color: #e0e0e0;
	border: 1px solid black;
	border-top: 0px
}

input#phrase {
	width: 30em;
	background-color: #e0f0f0;
}

input#username {
	width: 14em;
	background-color: #e0f0f0;
}

div.hidden {
	display: none;
}

span.from {
	font-weight: bold;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;div id=&quot;chat&quot;&gt;&lt;/div&gt;
	&lt;div id=&quot;input&quot;&gt;
		&lt;div id=&quot;join&quot;&gt;
			Username:&amp;nbsp;
			&lt;input id=&quot;username&quot; type=&quot;text&quot; /&gt;&lt;input id=&quot;joinB&quot;
				class=&quot;button&quot; type=&quot;submit&quot; name=&quot;join&quot; value=&quot;Join&quot; /&gt;
		&lt;/div&gt;
		&lt;div id=&quot;joined&quot; class=&quot;hidden&quot;&gt;
			Chat:&amp;nbsp;&lt;input id=&quot;phrase&quot; type=&quot;text&quot; /&gt; &lt;input id=&quot;sendB&quot;
				class=&quot;button&quot; type=&quot;submit&quot; name=&quot;join&quot; value=&quot;Send&quot; /&gt;
		&lt;/div&gt;
	&lt;/div&gt;
	
	&lt;script type=&quot;text/javascript&quot;&gt;	
		// 1) When user is NOT connected, 'join' div is displayed with Username input + Join button
		$('username').setAttribute('autocomplete', 'OFF');
		// Enter in the username field, opens Chat WebSockets
		$('username').onkeyup = function(ev) {
			var keyc = getKeyCode(ev);
			if (keyc == 13 || keyc == 10) {
				room.join($F('username'));
				return false;
			}
			return true;
		};
		// &quot;Join&quot; button click opens Chat WebSockets
		$('joinB').onclick = function(event) {
			room.join($F('username'));
			return false;
		};
		
		// 2) When user is connected, 'phrase' div is displayed with Chat input + Send button		
		$('phrase').setAttribute('autocomplete', 'OFF');
		// Enter in the 'phrase' field send the message
		$('phrase').onkeyup = function(ev) {
			var keyc = getKeyCode(ev);
			if (keyc == 13 || keyc == 10) {
				room.chat($F('phrase'));
				$('phrase').value = '';
				return false;
			}
			return true;
		};
		// &quot;Send&quot; button click send the message
		$('sendB').onclick = function(event) {
			room.chat($F('phrase'));
			$('phrase').value = '';
			return false;
		};
	&lt;/script&gt;
		
&lt;/body&gt;
&lt;/html&gt;
</pre></p>
<h2>Conclusion</h2>
<p>In this article we have implemented chat application on client side with JavaScript</strong> <a href="http://dev.w3.org/html5/websockets/">WebSocket</a>. In the next step <a href="http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step3/">[step3]</a> we will implement <strong>WebSockets on server side with Jetty-WebSocket</strong> and we will <strong>start the server with a Java main with Embedding Jetty</strong>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/angelozerr.wordpress.com/4859/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/angelozerr.wordpress.com/4859/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/angelozerr.wordpress.com/4859/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/angelozerr.wordpress.com/4859/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/angelozerr.wordpress.com/4859/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/angelozerr.wordpress.com/4859/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/angelozerr.wordpress.com/4859/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/angelozerr.wordpress.com/4859/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/angelozerr.wordpress.com/4859/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/angelozerr.wordpress.com/4859/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/angelozerr.wordpress.com/4859/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/angelozerr.wordpress.com/4859/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/angelozerr.wordpress.com/4859/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/angelozerr.wordpress.com/4859/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=4859&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://angelozerr.wordpress.com/2011/07/25/websockets_jetty_step2/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c3176f508ba2f224d3b00dce0ca6c2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">akrogen</media:title>
		</media:content>

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketstep2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview21.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview3.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview4.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview6.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview7.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview8.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview9.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_clientwebsocketoverview10.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_createchatui1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/jettywebsockets_createchatui2.png" medium="image" />
	</item>
		<item>
		<title>WebSockets with Embedding Jetty [step1]</title>
		<link>http://angelozerr.wordpress.com/2011/07/23/websockets_jetty_step1/</link>
		<comments>http://angelozerr.wordpress.com/2011/07/23/websockets_jetty_step1/#comments</comments>
		<pubDate>Sat, 23 Jul 2011 14:30:30 +0000</pubDate>
		<dc:creator>angelozerr</dc:creator>
				<category><![CDATA[Jetty]]></category>
		<category><![CDATA[WebSockets]]></category>

		<guid isPermaLink="false">http://angelozerr.wordpress.com/?p=4750</guid>
		<description><![CDATA[Since several years, WEB Application are more and more improved by using AJAX (Asynchronous JavaScript Technology and XML) to provide the same features than a Fat client (Swing, SWT Application). With AJAX, the client WEB Browser can communicate to server side with Javascript and can refresh only a fragment of the WEB Page and not [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=4750&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Since several years, WEB Application are more and more improved by using <strong>AJAX</strong> (Asynchronous JavaScript Technology and XML) to provide the same features than a Fat client (Swing, SWT Application). With AJAX, the <strong>client WEB Browser can communicate to server side with Javascript and can refresh only a fragment of the WEB Page and not the all page</strong>. A good sample of this feature is the <a href="http://www.google.com/talk/">GTalk</a> which is the Google GMail Chat Application. </p>
<p><strong>Chat Application with XMLHttpRequest (AJAX)</strong></p>
<p>AJAX is based on <a href="http://www.w3.org/TR/XMLHttpRequest/">XMLHttpRequest</a> which is W3C specification : </p>
<p><cite>The XMLHttpRequest specification defines an API that provides scripted client functionality for transferring data between a client and a server.</cite></p>
<p>Here a screen which shows you <strong>communication between client and server for GTalk Chat Application with AJAX</strong> : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/websocketsjetty_chatpapplicationwithajax.png?w=600" /></p>
<p>This schema shows you that there are 3 communications : </p>
<ul>
<li>[1] : Chat Application 1 send hello message.
  </li>
<li>[2] : Chat Application 2 poll the server to check if there are received messages.
  </li>
<li>[3] : Chat Application 2 receives the message (response of the [2] communication).
  </li>
</ul>
<p>You can see that in the Chat Application context <strong>with AJAX, there are a lot of communications between client and server side</strong> to check if there are received messages ([2] communication). WEB browser client must check every time if there are new received messages by polling the server (ex : the WEB Browser send every 5 seconds a request XMLHttpRequest to the server side to check if new messages are received). This solution can <strong>deteriorate the server performance</strong> because there are a lot of request just to check if they are new received messages (if they are no received messages, the response of this communication is not used).</p>
<p><strong>Chat Application with WebSockets</strong></p>
<p>To avoid a lot of communications between client and server side, the solution is that <strong>server should send a message to the client side</strong> as soon as it receives message <strong>without the client side polls the server</strong>. For his feature, HTML5 specify a new component called <a href="http://dev.w3.org/html5/websockets/">WebSockets</a>:</p>
<p><cite>This specification defines an API that enables Web pages to use the WebSocket protocol for two-way communication with a remote host</cite>. </p>
<p>Here a screen which shows you <strong>communication between client and server for GTalk Chat Application with WebSockets</strong> : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/07/websocketsjetty_chatpapplicationwithwebsockets.png?w=600" /></p>
<p>This schema shows you that there 3 comunications : </p>
<ol>
<li>[1] : Chat Application 1 send hello message
  </li>
<li>[2] : Chat Application 2 receives the message. The client NOT need to poll the server to check if new messages are received.
  </li>
</ol>
<p><strong>Chat Application Implementation</strong></p>
<p>WebSockets features are cool, but how to implement that? I will try to <strong>explain step by step how to develop a Chat Application on client/server side</strong> which will work in any JEE Server. I will use <a href="http://www.google.com/chrome/">Google Chrome</a>, a WEB Browser which supports WebSockets, to test the Chat Application.</p>
<p><span id="more-4750"></span></p>
<h2>Chat Application Implementation</h2>
<p>To implement a Chat Application with WebSockets you need to manage : </p>
<ul>
<li><strong>WebSockets on client side</strong>. For that the WEB Browser must support <a href="http://dev.w3.org/html5/websockets/">WebSockets</a> which is a Javascript object. Today <a href="http://www.google.com/chrome/">Google Chrome</a> implements this component. I have not studied the other WEB Browser which support WebSockets.
  </li>
<li><strong>WebSockets on server side</strong>. When I have started to study WebSockets, this point was very difficult for me because there is not a real specification. Each JEE Server implements WebSockets with their own solution (I think Servlet 3 specification should resolve that). Today it exists several solutions but for Java the only solution that I have done with success is <a href="http://www.eclipse.org/jetty/">Jetty Server</a> (I was not able to to manage WebSockets with <a href="http://grizzly.java.net/">Grizzly (Glassfish)</a> for instance). To manage WebSockets on server side, the <strong>server must manage asynchronous HTTP response</strong>.
  </li>
</ul>
<p>I was able to manage WebSockets only with <a href="http://www.eclipse.org/jetty/">Jetty Server</a>. But <strong>how to manage WebSockets with another JEE server</strong>? Indeed in professional job, the JEE server is often forced (in my case I must use WebSphere -(). I know that the goal of <a href="http://atmosphere.java.net/">Atmosphere</a> is to support the HTML5 WebSockets specification, but I have the impression this Framework use native WebSockets implementation of the JEE Server.  </p>
<p>To <strong>manage WebSockets in any JEE Server, I have found a solution by using Embedding Jetty</strong>. <strong>Embedding Jetty</strong> means that you can create, start and stop a Jetty Server with Java code. So you can create, start and stop a Jetty Server with few code in a Java main. The solution is very simply and I would like share you my idea with articles called <a href="http://angelozerr.wordpress.com/about/websockets_jetty/">WebSockets with Embedding Jetty</a> (you can find the plan in this link) by explaining step by step <strong>how to manage a Chat Application with Jetty-WebSockets</strong> and use a <a href="http://tomcat.apache.org/">Tomcat</a> Server as JEE Server. I will explain you : </p>
<ul>
<li>how to <strong>create Chat Application on client side</strong>. I will use <a href="http://www.google.com/chrome/">Google Chrome</a> to test the application.
  </li>
<li>how to <strong>create Chat Application on server side with Jetty-WebSockets</strong>.
  </li>
<li>how to <strong>start the Chat Application on server side with Java main with Embedding Jetty</strong>.
  </li>
<li>how to <strong>integrate Embedding Jetty in another JEE Server</strong>. I will use <a href="http://tomcat.apache.org/">Tomcat</a>.
</ul>
<p>This idea follow the same idea than <a href="http://code.google.com/p/gwt-ws/">WebSockets for GWT</a> with the <a href="http://code.google.com/p/google-web-toolkit/source/browse/trunk/dev/core/src/com/google/gwt/dev/shell/jetty/JettyLauncher.java">JettyLauncher</a>.</p>
<h2>Why I love Jetty?</h2>
<p>Before starting <a href="http://angelozerr.wordpress.com/about/websockets_jetty/">WebSockets with Embedding Jetty</a> articles, I would like just tell you why I love Jetty Server : </p>
<ul>
<li>Jetty is <strong>light</strong> (like Tomcat).</li>
<li>Jetty can be used in several context :
<ol>
<li>as <strong>JEE Server</strong>.</li>
<li>in <strong>OSGi context</strong>.</li>
<li>in a <strong>Java Main with Embedding Jetty</strong>.</li>
</ol>
</li>
<li>Jetty can be configured with several means :
<ol>
<li><strong>Jetty</strong> XML files.</li>
<li><strong>Spring</strong> XML files.</li>
<li><strong>Java code</strong>. (Embedding Jetty)</li>
</ol>
</li>
<li>Jetty Tools :
<ol>
<li>Tools for OSGi context. <a href="http://www.eclipse.org/rap/">Eclipse RAP</a> use Jetty by default to start the Application.</li>
<li>Tools for standard JEE : <a href="http://wiki.eclipse.org/Jetty_WTP_Plugin">Jetty WTP Adaptor</a> can be used in a Eclipse WTP to start/stop debug WEB Application deployed in a Jetty Server.
      </li>
</ol>
</li>
<li>Jetty <strong>support WebSockets</strong>.</li>
<li>For <strong>JUnit Tests WEB components</strong> (Servlet, Filter, Web Services&#8230;.), Embedding Jetty can be used to create JUnit Tests (to start a Jetty server and do the tests). For instance <a href="http://cxf.apache.org/">Apache CXF</a> uses Embedding  Jetty to tests WebServices, Rest services&#8230;.
  </li>
<li>Jetty is <strong>Open Source</strong> (Eclipse)</li>
<li><strong>Jetty Team is very enthusiasm</strong> and the <strong>Jetty the community is responsive</strong>.</li>
</ul>
<h2>Conclusion</h2>
<p>In this article we have seen how <strong>WebSockets could be used in a Chat Application</strong> and introduce <strong>WebSockets component on client/server side</strong>. In the next articles, I will explain you step by step <strong>how to develop Chat Application on client side (in the <a href="http://angelozerr.wordpress.com/2011/07/25/websockets_jetty_step2/">[step2]</a>) and server side with Jetty-WebSockets (in the <a href="http://angelozerr.wordpress.com/2011/07/26/websockets_jetty_step3/">[step3]</a>)</strong>. <strong>Embedding Jetty</strong> will be used to start/stop the server with Java main (no need to install a Jetty Server).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/angelozerr.wordpress.com/4750/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/angelozerr.wordpress.com/4750/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/angelozerr.wordpress.com/4750/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/angelozerr.wordpress.com/4750/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/angelozerr.wordpress.com/4750/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/angelozerr.wordpress.com/4750/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/angelozerr.wordpress.com/4750/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/angelozerr.wordpress.com/4750/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/angelozerr.wordpress.com/4750/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/angelozerr.wordpress.com/4750/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/angelozerr.wordpress.com/4750/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/angelozerr.wordpress.com/4750/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/angelozerr.wordpress.com/4750/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/angelozerr.wordpress.com/4750/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=4750&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://angelozerr.wordpress.com/2011/07/23/websockets_jetty_step1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c3176f508ba2f224d3b00dce0ca6c2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">akrogen</media:title>
		</media:content>

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/websocketsjetty_chatpapplicationwithajax.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/07/websocketsjetty_chatpapplicationwithwebsockets.png" medium="image" />
	</item>
		<item>
		<title>My first steps with Eclipse RAP [step6]</title>
		<link>http://angelozerr.wordpress.com/2011/05/31/rap_step6/</link>
		<comments>http://angelozerr.wordpress.com/2011/05/31/rap_step6/#comments</comments>
		<pubDate>Tue, 31 May 2011 13:51:40 +0000</pubDate>
		<dc:creator>angelozerr</dc:creator>
				<category><![CDATA[Eclipse RAP]]></category>

		<guid isPermaLink="false">http://angelozerr.wordpress.com/?p=4121</guid>
		<description><![CDATA[In step5, we have explained the generated code of the RAP Hello World Application. In this step we will improve our RAP Application to add basic user-interface (UI). At the end of this article, our RAP Application will look like this : In RAP/RCP Application, UI is managed with SWT (Standard Widget Toolkit) : SWT [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=4121&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://angelozerr.wordpress.com/2011/05/24/rap_step5/">step5</a>, we have <strong>explained the generated code</strong> of the RAP Hello World Application. In this step we will improve our RAP Application to <strong>add basic user-interface (UI)</strong>. At the end of this article, our RAP Application will look like this : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_step6overview.png?w=600" /></p>
<p>In RAP/RCP Application, UI is managed with <strong><a href="http://www.eclipse.org/swt/">SWT</a> (Standard Widget Toolkit)</strong> : </p>
<p><cite>SWT is an open source widget toolkit for Java designed to provide efficient, portable access to the user-interface facilities of the operating systems on which it is implemented.</cite></p>
<p><a href="http://www.eclipse.org/swt/">SWT</a> is an API to manage UI. There are <strong>several implementation of SWT</strong> : </p>
<ul>
<li>for <strong>RCP Application</strong>, the basic idea of SWT is to <strong>use the operating systems (OS) native widget to render UI</strong>. There is an implementation of  SWT for each OS (Windows, Linux&#8230;). Swing for instance emulates the UI widgets, that&#8217;s why the look and feel of Swing Application are the same for any OS, although look and feel of SWT Application change according to the OS (a button in SWT Application use Windows button look and feel if the SWT Application runs on Windows, use Linux button look and feel if the SWT Application runs on Linux..)..
  </li>
<li>for <strong>RAP Application</strong>, SWT is implemented with <strong><a href="http://qooxdoo.org/">Qooxdoo</a></strong> Javascript widgets. The SWT implementation in RAP Application is called <strong><a href="http://wiki.eclipse.org/WidgetToolkit">RWT</a> (Rich Widget Toolkit)</strong>. We will study it in the next article.
  </li>
</ul>
<p><span id="more-4121"></span></p>
<h2 id="download">Download</h2>
<p>You can download <a href="http://dl.dropbox.com/u/2903680/wordpress-blog/tutoriels/eclipse/rap/step6/rap_step6.zip">rap_step6.zip</a> which contains the following explained projects : </p>
<ul>
<li><strong>org.akrogen.dynaresume.raphelloworld</strong> which is the generated Eclipse &#8220;RAP Hello World&#8221; explained in this article.</li>
</ul>
<h2>Add UI SWT Text/Label</h2>
<p>In this section we will <strong>add the UI Text and Label</strong> to our RAP Application. In a RAP Application, UI Text, Label&#8230; widgets are managed with SWT API like RCP Application. The difference between RAP Application and RCP Application is the implementation of the SWT : </p>
<ul>
<li>in RCP Application, SWT is implemented with the OS native widgets. For instance for Windows OS, <strong>org.eclipse.swt.win32.win32.x86</strong> Plug-In is used.
  </li>
<li>in RCP Application, SWT is implemented with RWT which generates Javascript Qooxdoo widgets.<strong> org.eclipse.rap.rwt</strong> Plug-In is the SWT RAP widgets.
  </li>
</ul>
<p>To add UI widgets in our RAP Application, we must (like RCP Application) : </p>
<ol>
<li><a href="#CreateUserDetailView">create a View</a> which hosts SWT Text/Label</strong>.
  </li>
<li><a href="#LinkViewToPerspective">link the View to the default Perspective</a>.
  </li>
</ol>
<h3 id="CreateUserDetailView">Create UserDetailView View</h3>
<p>Creating the View consists of : </p>
<ul>
<li><a href="#declareView">declaring the view linked to the View class in the plugin.xml as extension point</a>. An <strong>extension point is used to extend</strong> your RAP/RCP Application. In our case we want to extend our RAP Application to add a new View.
  </li>
<li>creating the org.akrogen.dynaresume.raphelloworld.<strong><a href="#UserDetailViewClass">UserDetailView</a></strong> View class which extends org.eclipse.ui.part.<strong>ViewPart</strong>.
  </li>
</ul>
<h4 id="declareView">Declare View in the plugin.xml</h4>
<p>Declare our view in the plugin.xml will be done like this : </p>
<p><pre class="brush: xml;">&lt;extension
      point=&quot;org.eclipse.ui.views&quot;&gt;
   &lt;view
         class=&quot;org.akrogen.dynaresume.raphelloworld.UserDetailView&quot;
         id=&quot;org.akrogen.dynaresume.raphelloworld.userdetailview&quot;
         name=&quot;User Detail View&quot;
         restorable=&quot;true&quot;&gt;
   &lt;/view&gt;
&lt;/extension&gt;
</pre></p>
<p>but it&#8217;s interesting to use PDE Tools to generate the View. To do that, open the org.akrogen.dynaresume.raphelloworld<strong>/plugin.xml</strong>, go to the <strong>Extrensions</strong> tab and click on <strong>Add&#8230;</strong> button of the <strong>All Extensions</strong> section : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview1.png?w=600"></p>
<p>This action opens the <strong>New Extension</strong> dialogue : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview2.png?w=600"></p>
<p>This dialogue shows you all the extension points that you can use in your RAP Application. In our case we must use <strong>org.eclipse.ui.views</strong>. To do that, type <strong>*view</strong> in the <strong>Extension Point filter</strong>, 2 (or more) extension points must appear : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview3.png?w=600"></p>
<p>Select <strong>org.eclipse.ui.views</strong> item and click on <strong>Finish</strong> button. This action add this extension : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview4.png?w=600"></p>
<p>If you go to the plugin.xml, you will see the new extension point : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview5.png?w=600"></p>
<p>Now we must link the View extension point to our View class. To do that select <strong>org.eclipse.ui.views</strong> node, click on the right mouse button to open the contextual menu and click on <strong>view</strong> node : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview6.png?w=600"></p>
<p>This action generates you the content of the <strong>org.eclipse.ui.views</strong> extension point : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview7.png?w=600"></p>
<p>Change fields values : </p>
<ul>
<li><strong>id</strong> field with <strong>org.akrogen.dynaresume.raphelloworld.userdetailview</strong> value.
  </li>
<li><strong>name</strong> field with <strong>User Detail View</strong> value.
  </li>
<li><strong>class</strong> field with <strong>org.akrogen.dynaresume.raphelloworld.UserDetailView</strong> value.
  </li>
</ul>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview8.png?w=600"></p>
<p>If you go to the plugin.xml, you will see the new extension point : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview9.png?w=600"></p>
<h4 id="UserDetailViewClass">UserDetailView Class</h4>
<p>In this section we will create the org.akrogen.dynaresume.raphelloworld.<strong>UserDetailView</strong>  View class. Click on <strong>class*</strong> link : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview10.png?w=600"></p>
<p>This action opens the <strong>New Java Class</strong> wizard : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview11.png?w=600"></p>
<p>Click on <strong>Finish</strong> button, the wizard generates you org.akrogen.dynaresume.raphelloworld.<strong>UserDetailView</strong> class like this : </p>
<p><pre class="brush: java;">package org.akrogen.dynaresume.raphelloworld;

import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;

public class UserDetailView extends ViewPart {

	public UserDetailView() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void createPartControl(Composite parent) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub

	}

}</pre></p>
<h3 id="LinkViewToPerspective">Link View with Perspective</h3>
<p>Now we must link Perspective with the UserDetailView, the id <strong>org.akrogen.dynaresume.raphelloworld.userdetailview</strong> of the view declared in the plugin.xml will be used.</p>
<h4>Modify UserDetailView</h4>
<p>Modify the org.akrogen.dynaresume.raphelloworld.<strong>UserDetailView</strong> class to add the view ID in the Java code : </p>
<p><pre class="brush: java;">public static final String ID = &quot;org.akrogen.dynaresume.raphelloworld.userdetailview&quot;;</pre></p>
<p>Here is the full code of org.akrogen.dynaresume.raphelloworld.<strong>UserDetailView</strong>  : </p>
<p><pre class="brush: java;">package org.akrogen.dynaresume.raphelloworld;

import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;

public class UserDetailView extends ViewPart {

	public static final String ID = &quot;org.akrogen.dynaresume.raphelloworld.userdetailview&quot;;
	
	public UserDetailView() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void createPartControl(Composite parent) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub

	}

}</pre></p>
<h4>Modify Perspective</h4>
<p>Modify org.akrogen.dynaresume.raphelloworld.<strong>Perspective</strong> like this : </p>
<p><pre class="brush: java;">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) {
    String editorArea = layout.getEditorArea();
    layout.setEditorAreaVisible(false);
    layout.setFixed(true);

    layout.addStandaloneView(UserDetailView.ID, false, IPageLayout.LEFT,
        1.0f, editorArea);
  }
}</pre></p>
<p>Here we have linked the view to the Perspective with Java code.</p>
<h2>RWT Text/Label</h2>
<p>At this step the Perspective hosts the UserDetailView View. Now we can add UI widgets to the View by implementing <strong>UserDetailView#createPartControl(Composite parent)</strong>. When you want to manage UI with SWT you can use : </p>
<ul>
<li><a href="#SWTWidgets">SWT widgets</a> to displays Text, Label&#8230;.
  </li>
<li><a href="#SWTLayout">SWT layout</a> to manage layout of the parent container of the widgets.
  </li>
<li><a href="#SWTLayoutData">SWT layouts data</a> to customize layout for a widgets which belongs to an host container.
<li><a href="#SWTListener">SWT listener</a> to add/remove listener to the widget if you want to observe some events of the widget (text changed, focus in/out&#8230;).
  </li>
</ul>
<h3 id="SWTWidgets">SWT widgets</h3>
<p>SWT provides rich widgets which extend org.eclipse.swt.widgets.<strong>Widget</strong> (Text, Label, Tree, Table&#8230;.). You can see the screen of SWT Widgets <a href="http://www.eclipse.org/swt/widgets/">here</a>.</p>
<p>In our case, implement <strong>UserDetailView#createPartControl(Composite parent)</strong> like this : </p>
<p><pre class="brush: java;">@Override
public void createPartControl(Composite parent) {
	// User name
	Label nameLabel = new Label(parent, SWT.NONE);
	nameLabel.setText(&quot;Name:&quot;);
	Text nameText = new Text(parent, SWT.BORDER);

	// User lastName
	Label lastNameLabel = new Label(parent, SWT.NONE);
	lastNameLabel.setText(&quot;Last name:&quot;);
	Text lastNameText = new Text(parent, SWT.BORDER);
}</pre></p>
<p>The SWT.BORDER set a border for SWT Text. </p>
<p>Here is the full code of org.akrogen.dynaresume.raphelloworld.<strong>UserDetailView</strong> : </p>
<p><pre class="brush: java;">package org.akrogen.dynaresume.raphelloworld;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;

public class UserDetailView extends ViewPart {

	public static final String ID = &quot;org.akrogen.dynaresume.raphelloworld.userdetailview&quot;;
	
	public UserDetailView() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void createPartControl(Composite parent) {
		// User name
		Label nameLabel = new Label(parent, SWT.NONE);
		nameLabel.setText(&quot;Name:&quot;);
		Text nameText = new Text(parent, SWT.BORDER);

		// User lastName
		Label lastNameLabel = new Label(parent, SWT.NONE);
		lastNameLabel.setText(&quot;Last name:&quot;);
		Text lastNameText = new Text(parent, SWT.BORDER);

	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub

	}

}</pre></p>
<p><a href="http://angelozerr.wordpress.com/2011/05/10/rap_step1/#LaunchRAPApplication">Launch the RAP Application</a> and you will see our basic UI composed with RWT Text and Label : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_adduitoview1.png?w=600" /></p>
<p>This render is not very pretty because we didn&#8217;t use <a href="#SWTLayout">SWT Layout</a> to position the widgets.</p>
<h3 id="SWTLayout">SWT Layout</h3>
<p>In this section we will use SWT Layout to position as we want the SWT widgets Label and Text. All SWT Layouts extend the abstract org.eclipse.swt.widgets.<strong>Layout</strong> class.</p>
<p>I suggest you to read <a href="http://www.eclipse.org/articles/article.php?file=Article-Understanding-Layouts/index.html">Understanding Layouts in SWT</a> if you want to learn more about SWT Layout. The SWT Layout that I use is the org.eclipse.swt.layout.<strong>GridLayout</strong> which manages a lot of case. GridLayout can be compared to the layout used for HTML table. In this section we will use org.eclipse.swt.widgets.<strong>GridLayout</strong> to have this render : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_adduitoview2.png?w=600" /></p>
<p>Modify <strong>UserDetailView#createPartControl(Composite parent)</strong> like this : </p>
<p><pre class="brush: java;">@Override
public void createPartControl(Composite parent) {

	Composite composite = new Composite(parent, SWT.NONE);
	composite.setLayout(new GridLayout(2, false));

	// User name
	Label nameLabel = new Label(composite, SWT.NONE);
	nameLabel.setText(&quot;Name:&quot;);
	Text nameText = new Text(composite, SWT.BORDER);

	// User lastName
	Label lastNameLabel = new Label(composite, SWT.NONE);
	lastNameLabel.setText(&quot;Last name:&quot;);
	Text lastNameText = new Text(composite, SWT.BORDER);
}</pre></p>
<p>It&#8217;s important to create a new Composite parent instead of using the Composite parent coming from createPartControl, because this last has already a layout (FillLayout). If you change the Layout of the Composite parent coming from createPartControl you could have some problems with SWT LayoutData ClassCastException  (please see <a href="#SWTLayoutData">SWT Layout Data</a> section).</p>
<p>Here is the full code of the org.akrogen.dynaresume.raphelloworld.<strong>UserDetailView</strong> : </p>
<p><pre class="brush: java;">package org.akrogen.dynaresume.raphelloworld;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;

public class UserDetailView extends ViewPart {

	public static final String ID = &quot;org.akrogen.dynaresume.raphelloworld.userdetailview&quot;;

	public UserDetailView() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void createPartControl(Composite parent) {

		Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayout(new GridLayout(2, false));

		// User name
		Label nameLabel = new Label(composite, SWT.NONE);
		nameLabel.setText(&quot;Name:&quot;);
		Text nameText = new Text(composite, SWT.BORDER);

		// User lastName
		Label lastNameLabel = new Label(composite, SWT.NONE);
		lastNameLabel.setText(&quot;Last name:&quot;);
		Text lastNameText = new Text(composite, SWT.BORDER);
	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub

	}

}</pre></p>
<p><a href="http://angelozerr.wordpress.com/2011/05/10/rap_step1/#LaunchRAPApplication">Launch the RAP Application</a> and you will see our basic UI composed with RWT Text and Label : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_adduitoview2.png?w=600" /></p>
<h3 id="SWTLayoutData">SWT Layout Data</h3>
<p>If you want to customize the layout for a widget, you must use Layout Data. A Layout Data is linked to the SWT Layout which is used for the Composite which hosts widgets. You cannot use for instance RowData in the widget where Composite parent use GridLayout. In our case we will use org.eclipse.swt.layout.<strong>GridData</strong> for SWT Text so those widgets will take the full space : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_adduitoview3.png?w=600" /></p>
<p>Modify <strong>UserDetailView#createPartControl(Composite parent)</strong> like this : </p>
<p><pre class="brush: java;">@Override
public void createPartControl(Composite parent) {

	Composite composite = new Composite(parent, SWT.NONE);
	composite.setLayout(new GridLayout(2, false));

	// User name
	Label nameLabel = new Label(composite, SWT.NONE);
	nameLabel.setText(&quot;Name:&quot;);
	Text nameText = new Text(composite, SWT.BORDER);
	nameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

	// User lastName
	Label lastNameLabel = new Label(composite, SWT.NONE);
	lastNameLabel.setText(&quot;Last name:&quot;);
	Text lastNameText = new Text(composite, SWT.BORDER);
	lastNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
}</pre></p>
<p>Here is the full code of the org.akrogen.dynaresume.raphelloworld.<strong>UserDetailView</strong> : </p>
<p><pre class="brush: java;">package org.akrogen.dynaresume.raphelloworld;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;

public class UserDetailView extends ViewPart {

	public static final String ID = &quot;org.akrogen.dynaresume.raphelloworld.userdetailview&quot;;

	public UserDetailView() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void createPartControl(Composite parent) {

		Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayout(new GridLayout(2, false));

		// User name
		Label nameLabel = new Label(composite, SWT.NONE);
		nameLabel.setText(&quot;Name:&quot;);
		Text nameText = new Text(composite, SWT.BORDER);
		nameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		// User lastName
		Label lastNameLabel = new Label(composite, SWT.NONE);
		lastNameLabel.setText(&quot;Last name:&quot;);
		Text lastNameText = new Text(composite, SWT.BORDER);
		lastNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub

	}

}</pre></p>
<p><a href="http://angelozerr.wordpress.com/2011/05/10/rap_step1/#LaunchRAPApplication">Launch the RAP Application</a> and you will see our basic UI composed with RWT Text and Label : </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_adduitoview3.png?w=600" /></p>
<h2 id="SWTListener">SWT Listener</h2>
<p>Sometimes you want to observe with listener the change of state of the widgets. This is done with SWT Listener.  In our case, we will add a new Label on the top of the UI and display the Name+Last Name as soon as the user types a content in the SWT Text. </p>
<p>Modify  org.akrogen.dynaresume.raphelloworld.<strong>UserDetailView</strong> class like this : </p>
<p><pre class="brush: java;">@Override
public void createPartControl(Composite parent) {

	Composite composite = new Composite(parent, SWT.NONE);
	composite.setLayout(new GridLayout(2, false));

	// User 
	final Label userLabel = new Label(composite, SWT.NONE);
	GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
	gridData.horizontalSpan = 2;
	userLabel.setLayoutData(gridData);
		
	// User name
	Label nameLabel = new Label(composite, SWT.NONE);
	nameLabel.setText(&quot;Name:&quot;);
	final Text nameText = new Text(composite, SWT.BORDER);
	nameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
	//nameText.setLayoutData(new GridData(SWT.FILL, 1, true, false));

	// User lastName
	Label lastNameLabel = new Label(composite, SWT.NONE);
	lastNameLabel.setText(&quot;Last name:&quot;);
	final Text lastNameText = new Text(composite, SWT.BORDER);
	lastNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		
	// Add Listener
	nameText.addModifyListener(new ModifyListener() {			
		@Override
		public void modifyText(ModifyEvent event) {
			userLabel.setText(nameText.getText() + &quot; &quot; + lastNameText.getText());
		}
	});
	// Add Listener
	lastNameText.addModifyListener(new ModifyListener() {			
		@Override
		public void modifyText(ModifyEvent event) {
			userLabel.setText(nameText.getText() + &quot; &quot; + lastNameText.getText());
		}
	});
}</pre></p>
<p>You can notice that : </p>
<ul>
<li>SWT Text are final because they are used in the inner class of the SWT event listener.
  </li>
<li>SWT Label User (first label) use <strong>gridData.horizontalSpan = 2;</strong> which shows you another case with SWT GridLayout which is enable to support span.
  </li>
</ul>
<p>Here is the full code of org.akrogen.dynaresume.raphelloworld.<strong>UserDetailView</strong>  : </p>
<p><pre class="brush: java;">package org.akrogen.dynaresume.raphelloworld;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;

public class UserDetailView extends ViewPart {

	public static final String ID = &quot;org.akrogen.dynaresume.raphelloworld.userdetailview&quot;;

	public UserDetailView() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void createPartControl(Composite parent) {

		Composite composite = new Composite(parent, SWT.NONE);
		composite.setLayout(new GridLayout(2, false));

		// User 
		final Label userLabel = new Label(composite, SWT.NONE);
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalSpan = 2;
		userLabel.setLayoutData(gridData);
		
		// User name
		Label nameLabel = new Label(composite, SWT.NONE);
		nameLabel.setText(&quot;Name:&quot;);
		final Text nameText = new Text(composite, SWT.BORDER);
		nameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		//nameText.setLayoutData(new GridData(SWT.FILL, 1, true, false));

		// User lastName
		Label lastNameLabel = new Label(composite, SWT.NONE);
		lastNameLabel.setText(&quot;Last name:&quot;);
		final Text lastNameText = new Text(composite, SWT.BORDER);
		lastNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		
		// Add Listener
		nameText.addModifyListener(new ModifyListener() {			
			@Override
			public void modifyText(ModifyEvent event) {
				userLabel.setText(nameText.getText() + &quot; &quot; + lastNameText.getText());
			}
		});
		// Add Listener
		lastNameText.addModifyListener(new ModifyListener() {			
			@Override
			public void modifyText(ModifyEvent event) {
				userLabel.setText(nameText.getText() + &quot; &quot; + lastNameText.getText());
			}
		});
	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub

	}

}</pre></p>
<p><a href="http://angelozerr.wordpress.com/2011/05/10/rap_step1/#LaunchRAPApplication">Launch the RAP Application</a> and type content in the &#8220;Name&#8221; text widget: </p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_addlistenertoui1.png?w=600" /></p>
<p>You will see that the Label User is refreshed with SWT Text Name content.  Type content in the &#8220;Last name&#8221; text widget:  You will see that the Label User is refreshed with SWT Text Name+SWT Text &#8220;Last Name&#8221;  content.</p>
<p><img src="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_addlistenertoui2.png?w=600" /></p>
<p><H2>Conclusion</h2>
<p>In this article we have seen how to manage UI in RAP Application with only Java code (RWT which is SWT implementation for RAP). RCP Application manage also UI with SWT, so it&#8217;s very easy to manage Single Sourcing to have with the same code a RCP/RAP Application. </p>
<p>Creating UI manually can be boring, but fortunately there is an Eclipse Plug-In <a href="http://code.google.com/intl/fr/javadevtools/wbpro/">WindowBuilder</a>  which provides <strong>SWT Designer</strong> to help you create UI with design way. <a href="http://code.google.com/intl/fr/javadevtools/wbpro/layoutmanagers/swt/gridlayout.html">WindowBuilder &#8211; SWT GridLayout</a> section shows you how it&#8217;s possible to design UI with SWT GridLayout. </p>
<p>In the next article <a href="http://angelozerr.wordpress.com/2011/08/08/rap_step7/">[step7]</a> : create RAP Application with a view by using <a href="http://www.eclipse.org/rap/downloads/1.4/">RAP 1.4</a>, create RCP Application with a view and compare it with RAP Application.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/angelozerr.wordpress.com/4121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/angelozerr.wordpress.com/4121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/angelozerr.wordpress.com/4121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/angelozerr.wordpress.com/4121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/angelozerr.wordpress.com/4121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/angelozerr.wordpress.com/4121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/angelozerr.wordpress.com/4121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/angelozerr.wordpress.com/4121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/angelozerr.wordpress.com/4121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/angelozerr.wordpress.com/4121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/angelozerr.wordpress.com/4121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/angelozerr.wordpress.com/4121/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/angelozerr.wordpress.com/4121/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/angelozerr.wordpress.com/4121/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=angelozerr.wordpress.com&amp;blog=10338309&amp;post=4121&amp;subd=angelozerr&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://angelozerr.wordpress.com/2011/05/31/rap_step6/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/4c3176f508ba2f224d3b00dce0ca6c2a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">akrogen</media:title>
		</media:content>

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_step6overview.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview3.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview4.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview5.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview6.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview7.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview8.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview9.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview10.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_createview11.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_adduitoview1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_adduitoview2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_adduitoview2.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_adduitoview3.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_adduitoview3.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_addlistenertoui1.png" medium="image" />

		<media:content url="http://angelozerr.files.wordpress.com/2011/05/myfirststepwithrap_addlistenertoui2.png" medium="image" />
	</item>
	</channel>
</rss>
