<?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/"
	>

<channel>
	<title>Bristol – Google Technology User Group</title>
	<atom:link href="http://www.bristol-gtug.org/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.bristol-gtug.org</link>
	<description>Bristol – Google Technology User Group</description>
	<lastBuildDate>Thu, 20 May 2010 13:27:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Google I/O 2010</title>
		<link>http://www.bristol-gtug.org/?p=151</link>
		<comments>http://www.bristol-gtug.org/?p=151#comments</comments>
		<pubDate>Thu, 20 May 2010 13:27:05 +0000</pubDate>
		<dc:creator>Daniel Vaughan</dc:creator>
				<category><![CDATA[GWT]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://www.bristol-gtug.org/?p=151</guid>
		<description><![CDATA[Google I/O is on at the moment so expect lots of announcements.
The most interesting I have come across so far is new integration between GWT and Spring. This sound promising as these are two of my preferred technologies: http://www.vmware.com/company/news/releases/vmware-google.html
You can keep up with videos from Google I/O here:
http://www.youtube.com/googledevelopers
]]></description>
			<content:encoded><![CDATA[<p>Google I/O is on at the moment so expect lots of announcements.</p>
<p>The most interesting I have come across so far is new integration between GWT and Spring. This sound promising as these are two of my preferred technologies: http://www.vmware.com/company/news/releases/vmware-google.html</p>
<p>You can keep up with videos from Google I/O here:</p>
<p>http://www.youtube.com/googledevelopers</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bristol-gtug.org/?feed=rss2&amp;p=151</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mobile Widgets with GWT with Spring and JSONP</title>
		<link>http://www.bristol-gtug.org/?p=76</link>
		<comments>http://www.bristol-gtug.org/?p=76#comments</comments>
		<pubDate>Tue, 09 Mar 2010 20:07:13 +0000</pubDate>
		<dc:creator>Daniel Vaughan</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[GWT]]></category>
		<category><![CDATA[Nokia WRT]]></category>
		<category><![CDATA[jsonp]]></category>
		<category><![CDATA[mobile widgets]]></category>
		<category><![CDATA[nokia]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[wrt]]></category>

		<guid isPermaLink="false">http://www.bristol-gtug.org/?p=76</guid>
		<description><![CDATA[View Daniel Vaughan&#8217;s profile
Over the past couple of weeks I have been looking at the feasibility of creating mobile widgets using Google Web Toolkit (GWT).  Mobile widgets package up open web technology, specifically HTML, CSS, JavaScript files in such a way that they can be deployed as  applications on mobile phones.  In a similar way the same files could be packaged to deploy as Opera widgets or Adobe Air applications. The productivity gain of writing code once like this and being able to execute it on so many platforms is very appealing especially for ...]]></description>
			<content:encoded><![CDATA[<div><a style="text-decoration: none;" href="http://uk.linkedin.com/in/danielpvaughan"><span style="font: 80% Arial,sans-serif; color: #0783b6;"><img style="vertical-align: middle;" src="http://www.linkedin.com/img/webpromo/btn_in_20x15.png" border="0" alt="View Daniel Vaughan's LinkedIn profile" width="20" height="15" />View Daniel Vaughan&#8217;s profile</span></a><br />
Over the past couple of weeks I have been looking at the feasibility of creating <a href="http://en.wikipedia.org/wiki/Mobile_Widgets" target="_blank">mobile widgets</a> using <a href="file:///S:/My%20Dropbox/Work/GWT%20JSONP/Google%20W%20eb%20Toolkit" target="_blank">Google Web Toolkit</a> (GWT).  Mobile widgets package up open web technology, specifically HTML, CSS, JavaScript files in such a way that they can be deployed as  applications on mobile phones.  In a similar way the same files could be packaged to deploy as <a href="http://widgets.opera.com/" target="_blank">Opera widgets</a> or <a href="http://en.wikipedia.org/wiki/Adobe_Integrated_Runtime" target="_blank">Adobe Air</a><span style="text-decoration: underline;"> </span>applications. The productivity gain of writing code once like this and being able to execute it on so many platforms is very appealing especially for developers who have to target multiple mobile platforms.</p>
<h2>A GWT solution</h2>
<p>The programming language I am most comfortable with is Java and for web application I have been using GWT extensively for the last couple years. GWT compiles Java into optimised, cross-browser JavaScript. This has a number of advantages some of the most important of which are the ability to debug and test code using the wide range of Java based tools.</p>
<p>With this in mind I thought GWT would be the ideal tool for ideal for creating a JavaScript application to package up into a mobile widget. I set off making a proof of concept last week. The proof of concept, based on a standard GWT example application was successful and with a few tweaks I was quickly able to deploy a GWT based mobile widget, in that case a <a href="http://www.forum.nokia.com/Technology_Topics/Web_Technologies/Web_Runtime/" target="_blank">Nokia Web Runtime</a> (WRT) widget, to my <a href="http://europe.nokia.com/find-products/devices/nokia-e72" target="_blank">Nokia E72</a> mobile phone.</p>
<p>One of the great features of GWT however is the ability it gives to JavaScript to communicate with backend Java services via a mechanism called GWT RPC. In the work I do this is very useful as there are  plenty of Java based backend services that need to be accessed. This mechanism works by the client (JavaScript) code and the server (Java) code being deployed together in the same war file and in the web container. However, when the JavaScript alone is packaged up in a widget the web container is not there and so there is nowhere for the server Java code to run. This means that in the case of widgets I had to look at a different way of communicating with the server.</p>
<p>Since server calls from a mobile client will be going across a relatively slow and unreliable 3G or worse mobile connection I wanted to keep the mechanism as light weight as possible. Using simple <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer" target="_blank">REST</a> services with <a href="http://www.json.org/" target="_blank">JSON</a> data seemed like a good approach. However the JavaScript that calls the service would be in a mobile widget effectively running on a local server on the mobile phone. The JSON service would be on a remote server and this will cause <a href="http://en.wikipedia.org/wiki/Cross-site_scripting" target="_blank">cross-site scripting</a> issues due to the <a href="http://en.wikipedia.org/wiki/Same_origin_policy" target="_blank">same origin policy</a>.</p>
<p>This led me to look at <a href="http://en.wikipedia.org/wiki/JSONP#JSONP" target="_blank">JSONP</a> (JSON with padding). JSONP allows you to pad the JSON data that is returned from the server with a JavaScript callback function.  This means that when the response comes back from the server the callback function is called on the client to do something meaningful with the data. As the call is performed within a script tag the same origin policy does not apply and so the client can consume the service residing on the remote server.</p>
<h2>How to implement it</h2>
<p>I wanted to make this work using GWT for my client and Spring as the framework for the server services. Looking on the web there were lots of articles about JSON with Spring, GWT with JSON and I even found a couple that had GWT, Spring and JSON together.</p>
<p>GWT and Spring move very quickly and pretty much everything  even articles that were a few months old were out of date or at least in the latest version of Spring or GWT there seemed to be a better way of doing something.  It always starts to get worrying when you see questions in forums that are relevant to what you are trying to do and then realising they are only one or two weeks old.</p>
<p>It was a bit of a struggle to break everything down and work out the simplest way to achieve my objective; making a JSONP request in GWT 2.0.2 to a remote service based on Spring 3.0 MVC and using the facilities available. Even then I had to take anything I produced one stage further by packaging the resultant GWT generated JavaScript as a mobile widget. I therefore decided to share my solution in the hope that others will be able to improve upon it. Please bear in mind that Spring MVC especially version 3.0 is still very new to me and as such I would appreciate any feedback.</p>
<p>The first thing I did was to follow the <a href="http://code.google.com/webtoolkit/doc/latest/tutorial/Xsite.html" target="_blank">making cross-site requests</a> tutorial in the web toolkit documentation. This uses Python or PHP on the server and does not use the most current GWT features for a JSONP call but it is GWT using JSONP.  I went through it and packaged up the resultant GWT generated JavaScript code into a mobile widget. The widget successfully installed on my Nokia E72 phone and I was able to confirm that what I wanted to do was possible. The phone made the JSONP service and data was returned.</p>
<p>Knowing that what I wanted to do was theoretically possible I set about making a proof of concept to using Spring one the server and prove that it was possible to make a JSONP request from GWT and get the correct response back while keeping code to a minimum. To keep it really simple all I wanted to achieve was to receive a person object with my name &#8220;Dan&#8221; back from the server.</p>
<h2>Part 1 &#8211; Server side</h2>
<h3>Dependencies</h3>
<p>I use maven for my dependency management so setup my pom to include the following packages:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="308" valign="top">Package</td>
<td width="308" valign="top">Version</td>
</tr>
<tr>
<td width="308" valign="top">spring-core</td>
<td width="308" valign="top">3.0.1.RELEASE</td>
</tr>
<tr>
<td width="308" valign="top">spring-context</td>
<td width="308" valign="top">3.0.1.RELEASE</td>
</tr>
<tr>
<td width="308" valign="top">spring-webmvc</td>
<td width="308" valign="top">3.0.1.RELEASE</td>
</tr>
<tr>
<td width="308" valign="top">com.springsource.org.codehaus.jackson.mapper</td>
<td width="308" valign="top">1.4.2</td>
</tr>
<tr>
<td width="308" valign="top">servlet-api</td>
<td width="308" valign="top">2.5</td>
</tr>
<tr>
<td width="308" valign="top">log4j</td>
<td width="308" valign="top">1.2.15</td>
</tr>
</tbody>
</table>
<h3>The Domain</h3>
<p>All that I wanted to do was get back a Person object from the server containing my name so ss I wanted to keep this as straight forwards as possible I defined the Person object as a simple bean.</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.danielvaughan.examples.jsonp.domain</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Person<br />
<span style="color: #009900;">&#123;</span><br />
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a> name<span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> Person<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a> name<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">name</span> <span style="color: #339933;">=</span> name<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a> getName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
<span style="color: #000000; font-weight: bold;">return</span> name<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<h3>The Controller</h3>
<p>The controller is almost as simple:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.danielvaughan.examples.jsonp.server.web</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.stereotype.Controller</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.ui.ModelMap</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.web.bind.annotation.RequestMapping</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.web.bind.annotation.RequestMethod</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.danielvaughan.examples.jsonp.domain.Person</span><span style="color: #339933;">;</span><br />
<br />
@Controller<br />
@RequestMapping<span style="color: #009900;">&#40;</span>value <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;/person/**&quot;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> PersonController<br />
<span style="color: #009900;">&#123;</span><br />
@RequestMapping<span style="color: #009900;">&#40;</span>method <span style="color: #339933;">=</span> RequestMethod.<span style="color: #006633;">GET</span>, params<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;callback&quot;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> getPerson<span style="color: #009900;">&#40;</span>ModelMap modelMap<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
Person person <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Dan&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
modelMap.<span style="color: #006633;">addAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;person&quot;</span>, person<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Here I am using Spring annotations. The @Controller annotation marks my class as a MVC Controller and the @RequestMapping annotation for the class tells it to accept requests on the person path.</p>
<p>The @RequestMapping on the getPerson() method tells it to respond to HTTP get requests that have the callback parameter set. This means that the URL for calling this from a browser would look like this: /person?callback=&lt;some JavaScipt method name&gt;.</p>
<p>The method creates a new person with the name &#8220;Dan&#8221; and adds it to the modelMap with the key person.</p>
<h3>Adding a custom view resolver</h3>
<p>In Spring 3.0 the MappingJacksonJsonView is included for providing a JSON view of a response to a request.  However, at the time of writing there is not a built in view that can provide me with what I want which is JSONP padding of the JSON view so as a quick solution until I work out a better one I just took a copy of the MappingJacksonView and modified the renderMergedOutputModel method to create my own MappingJacksonJsonpView.</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">@Override<br />
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> renderMergedOutputModel<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Amap+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Map</span></a> model, HttpServletRequest request, HttpServletResponse response<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Exception</span></a><br />
<span style="color: #009900;">&#123;</span><br />
<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aobject+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Object</span></a> value <span style="color: #339933;">=</span> filterModel<span style="color: #009900;">&#40;</span>model<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
JsonGenerator generator <span style="color: #339933;">=</span> objectMapper.<span style="color: #006633;">getJsonFactory</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">createJsonGenerator</span><span style="color: #009900;">&#40;</span>response.<span style="color: #006633;">getOutputStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, encoding<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a> callback <span style="color: #339933;">=</span> request.<span style="color: #006633;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;callback&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>callback<span style="color: #339933;">!=</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
prefixJson <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>prefixJson<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
generator.<span style="color: #006633;">writeRaw</span><span style="color: #009900;">&#40;</span>callback <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;(&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
objectMapper.<span style="color: #006633;">writeValue</span><span style="color: #009900;">&#40;</span>generator, value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
generator.<span style="color: #006633;">flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>prefixJson<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
generator.<span style="color: #006633;">writeRaw</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;);&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
generator.<span style="color: #006633;">flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>All I have done is to take the value of the callback parameter given in the request and use that to pad the generated JSON.  If anyone has a less messy way of doing this such as a servlet filter I would like to hear from you.  In the meantime I will work out a more permanent solution.</p>
<h3>Web configuration</h3>
<p>I now need to create my web.xml (src\main\webapps\WEB-INF\web.xml).</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"&gt;
&lt;display-name&gt;JSONP Example&lt;/display-name&gt;
&lt;display-name&gt;A simple example of serving JSONP&lt;/display-name&gt;
&lt;context-param&gt;
&lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt;
&lt;param-value&gt;
classpath:log4j.properties
&lt;/param-value&gt;
&lt;/context-param&gt;
&lt;listener&gt;
&lt;listener-class&gt;org.springframework.web.util.Log4jConfigListener&lt;/listener-class&gt;
&lt;/listener&gt;
&lt;!-- required to enable Spring 3.0 REST support --&gt;
&lt;filter&gt;
&lt;filter-name&gt;httpMethodFilter&lt;/filter-name&gt;
&lt;filter-class&gt;org.springframework.web.filter.HiddenHttpMethodFilter&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;httpMethodFilter&lt;/filter-name&gt;
&lt;servlet-name&gt;jsonp-example&lt;/servlet-name&gt;
&lt;/filter-mapping&gt;
&lt;!-- Servlets --&gt;
&lt;servlet&gt;
&lt;servlet-name&gt;jsonp-example&lt;/servlet-name&gt;
&lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
&lt;load-on-startup&gt;2&lt;/load-on-startup&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;jsonp-example&lt;/servlet-name&gt;
&lt;url-pattern&gt;/service/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
&lt;/web-app&gt;</pre>
<p>All I am doing here is defining my servlet.</p>
<h3>Spring configuration</h3>
<p>In my jsonp-example-servlet.xml (src\main\webapps\WEB-INF\jsonp-example-servlet.xml) I have the following:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"&gt;
&lt;!-- Sets up all handlers automatically and configures conversion services including Jackson if in classpath  --&gt;
&lt;mvc:annotation-driven /&gt;
&lt;!--  scans the base package looking for @Controllers etc to setup automatically --&gt;
&lt;context:component-scan base-package="com.danielvaughan.examples.jsonp.server.web" /&gt;
&lt;!--  adds a view for presenting the results of a request in JSON format  --&gt;
&lt;bean&gt;
&lt;property name="mediaTypes"&gt;
&lt;map&gt;
&lt;entry key="json" value="application/json" /&gt;
&lt;/map&gt;
&lt;/property&gt;
&lt;property name="defaultViews"&gt;
&lt;list&gt;
&lt;bean/&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;property name="viewResolvers"&gt;
&lt;list&gt;
&lt;bean /&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
&lt;/beans&gt;</pre>
<p>From what I can work out this is the minimum I need to get Spring to setup the correct handlers, pick up my annotations and wire everything together for me.  In the view resolver bean I tell spring to encode the response as the application/json MIME type and to use my MappingJsonpView view.</p>
<p>Now everything is in place and I just put the following URL in a browser which specifies the callback function as &#8220;myCallback&#8221;:</p>
<p><a href="http://127.0.0.1:8080/examples-jsonp/service/person?callback=myCallback">http://127.0.0.1:8080/examples-jsonp/service/person?callback=myCallback</a></p>
<p>I should  get a JSONP encoded person object with the name &#8220;Dan&#8221;, the desired result:</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">myCallback<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span><span style="color: #3366CC;">&quot;person&quot;</span><span style="color: #339933;">:</span><span style="color: #009900;">&#123;</span><span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;Dan&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>That is all I want to do on the server side. Now I will look at the GWT client.</p>
<h2>Part 2 &#8211; The Client</h2>
<p>Now I have a server with a service that will respond to JSONP requests I want to create a GWT client that will call the service and process the results. Again this is going to be as simple as possible. All I really want it to is perform the request and display my name in the browser.</p>
<p>I create a new GWT 2.0.2 project and remove pretty much all the GWT boiler plate code. In GWT JSONP support is a separate module called com.google.gwt.jsonp.Jsonp so I need to specify it in my gwt.xml . My gxt.xml file looks like this:</p>
<p>&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;UTF-8&#8243;?&gt;<br />
&lt;module rename-to=&#8217;examplejsonpclient&#8217;&gt;<br />
&lt;!&#8211; Inherit the core Web Toolkit stuff.                        &#8211;&gt;<br />
&lt;inherits name=&#8217;com.google.gwt.user.User&#8217; /&gt;<br />
&lt;!&#8211; Other module inherits                                      &#8211;&gt;<br />
&lt;inherits name=&#8217;com.google.gwt.jsonp.Jsonp&#8217; /&gt;<br />
&lt;!&#8211; Specify the app entry point class.                         &#8211;&gt;<br />
&lt;entry-point class=&#8217;com.danielvaughan.examples.jsonp.client.ExampleJsonpClient&#8217; /&gt;<br />
&lt;!&#8211; Specify the paths for translatable code                    &#8211;&gt;<br />
&lt;source path=&#8217;client&#8217; /&gt;<br />
&lt;/module&gt;</p>
<p>My html file and web.xml are absolutely minimal. In my EntryPoint class, ExampleJsonpClient, I add the following to the onModuleLoad() method:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onModuleLoad<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
<span style="color: #000000; font-weight: bold;">final</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Alabel+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Label</span></a> label <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Alabel+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Label</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
RootPanel.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>label<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Astring+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">String</span></a> url <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;http://127.0.0.1:8080/examples-jsonp/service/person&quot;</span><span style="color: #339933;">;</span><br />
JsonpRequestBuilder jsonp <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JsonpRequestBuilder<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
jsonp.<span style="color: #006633;">requestObject</span><span style="color: #009900;">&#40;</span>url, <span style="color: #000000; font-weight: bold;">new</span> AsyncCallback<br />
<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onFailure<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Athrowable+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Throwable</span></a> throwable<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
label.<span style="color: #006633;">setText</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Error: &quot;</span> <span style="color: #339933;">+</span> throwable<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onSuccess<span style="color: #009900;">&#40;</span>Person person<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
label.<span style="color: #006633;">setText</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Hello &quot;</span> <span style="color: #339933;">+</span> person.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>When I run the GWT application I get what I wanted in the browser:</p>
<p>Hello Dan</p>
<h2>Part 3 &#8211; The mobile client</h2>
<p>Now to make this into a mobile widget. All widget implementations seem to vary slightly regarding how the packaging is done but as I have a Nokia mobile phone I am going to package my widget as a Nokia WRT widget. It is my understanding that <a href="http://widgets.opera.com/" target="_blank">Opera Widgets</a>, <a href="http://www.adobe.com/products/air/develop/ajax/" target="_blank">Adobe Air</a> and iPhone Apps (via <a href="http://phonegap.com/" target="_blank">PhoneGap</a> or <a href="http://www.appcelerator.com/" target="_blank">Appcelerator</a>) and widgets for other platforms can all be packaged in a similar way the only differences usually being the extension of the zip file and the format of the configuration file.</p>
<h2>Putting the spring service on the web</h2>
<p>First however I  need to package up the spring project into a war file and deploy it somewhere that our mobile phone will be able to access such as a public facing web container like <a href="http://tomcat.apache.org/" target="_blank">Apache Tomcat</a> or a JEE server if you have access to one.</p>
<p>Another good place for services like these would be a cloud based service such as <a href="http://aws.amazon.com/ec2/" target="_blank">Amazon EC2</a> using something like Spring Source&#8217;s<a href="http://www.cloudfoundry.com/" target="_blank"> CloudFoundry</a><span style="text-decoration: underline;">.</span> It is likely <a href="http://code.google.com/appengine/" target="_blank">Google App Engine</a> would also be suitable for many applications and certainly would have no trouble for this one with a right setup.</p>
<p>Whatever then I need to update the URL referenced in the onModuleLoad method of our GWT apps&#8217; EntryPoint class to point at the URL of the deployed Spring service rather than the one running on the local host.</p>
<h2>Minimising the number of files</h2>
<p>As I want to minimise the size of the application I deploy to the mobile it is a good idea to setup the GWT compiler so that it produces the JavaScript only for the  target browser and not other browsers such as IE, Firefox etc. Since the browser on my Nokia phone is based on <a href="http://webkit.org/" target="_blank">WebKit</a> I only want output that is optimised for that browser so I add the following like to the gwt.xml file:</p>
<pre>&lt;set-property name="user.agent" value="gecko"/&gt;</pre>
<p>Compiling the GWT app now leaves us with far fewer files to our mobile widget with. It is also a good idea that the output style is set to Obfuscated for the smallest file size.</p>
<h2>Packaging as a mobile widget</h2>
<p>To package the project as a WRT widget I now need to create a file called Info.plist that looks like this:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Nokia//DTD PLIST 1.0//EN" "http://www.nokia.com/DTDs/plist-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
&lt;key&gt;DisplayName&lt;/key&gt;
&lt;string&gt;ExampleJsonpClient&lt;/string&gt;
&lt;key&gt;Identifier&lt;/key&gt;
&lt;string&gt;com.danielvaughan.examples.jsonp.client.ExampleJsonpClient&lt;/string&gt;
&lt;key&gt;Version&lt;/key&gt;
&lt;string&gt;1.0&lt;/string&gt;
&lt;key&gt;AllowNetworkAccess&lt;/key&gt;
&lt;true/&gt;
&lt;key&gt;MainHTML&lt;/key&gt;
&lt;string&gt;ExampleJsonpClient.html&lt;/string&gt;
&lt;key&gt;MiniViewEnabled&lt;/key&gt;
&lt;false/&gt;
&lt;/dict&gt;
&lt;/plist&gt;</pre>
<p>The important bits are the AllowNetworkAccess part which unsurprisingly lets the application connect to the internet and setting the MainHTML value to the GWT apps html file ExampleJsonpClient.html.</p>
<p>Now I  compile my GWT project take war\examplejsonpclient folder, ExampleJsonpClient.html and Info.plist and add them to a zip file. I name the zip file ExampleJsonpClient.wgz. The wgz extension is important as this is what identifies it as a mobile widget.</p>
<h2>Deploying</h2>
<p>Now all I need to do is transfer the ExampleJsonpClient.wgz file to my mobile phone. I just send it as a Bluetooth message. When I open the message I am prompted to install the widget and then I have an application I can run.</p>
<p>One running the application I get a blank screen with the same message as I had in my web browser:</p>
<p><a href="http://www.bristol-gtug.org/wp-content/uploads/2010/03/P1010108.jpg"><img class="alignleft size-medium wp-image-130" title="Hello Dan E72" src="http://www.bristol-gtug.org/wp-content/uploads/2010/03/P1010108-300x200.jpg" alt="Hello Dan on a Nokia E72" width="300" height="200" /></a></p>
<h2>Source code</h2>
<div>The source code for this application is available here:</div>
<ul>
<li><a href="http://www.bristol-gtug.org/wp-content/uploads/2010/03/client.zip" target="_blank">client.zip (10Kb)</a></li>
<li><a href="http://www.bristol-gtug.org/wp-content/uploads/2010/03/server.zip" target="_blank">server.zip (9Kb)</a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.bristol-gtug.org/?feed=rss2&amp;p=76</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Mobile Widgets and GWT</title>
		<link>http://www.bristol-gtug.org/?p=71</link>
		<comments>http://www.bristol-gtug.org/?p=71#comments</comments>
		<pubDate>Wed, 17 Feb 2010 17:03:12 +0000</pubDate>
		<dc:creator>Daniel Vaughan</dc:creator>
				<category><![CDATA[GWT]]></category>

		<guid isPermaLink="false">http://www.bristol-gtug.org/?p=71</guid>
		<description><![CDATA[I attended the OpenMIC BarCamp event in Bath last week and was interested to learn about mobile widgets. Mobile widgets are basically mobile apps build with web technologies. They come in different flavours but all are a collection of JavaScript, CSS and image files together with an HTML file. These files are then packaged in a zip file with an XML descriptor (a bit like a war) and can be deployed to a mobile phone. I just deployed my by sending the file via Bluetooth. The application then can be ...]]></description>
			<content:encoded><![CDATA[<p>I attended the <a href="http://openmicamp.ning.com" target="_blank">OpenMIC</a> BarCamp event in Bath last week and was interested to learn about <a href="http://en.wikipedia.org/wiki/Widget_engine#Mobile_widgets" target="_blank">mobile widgets</a>. Mobile widgets are basically mobile apps build with web technologies. They come in different flavours but all are a collection of JavaScript, CSS and image files together with an HTML file. These files are then packaged in a zip file with an XML descriptor (a bit like a war) and can be deployed to a mobile phone. I just deployed my by sending the file via Bluetooth. The application then can be started like a normal app although it is effectively a local web site running the browser full screen. Obviously the big wins here are that the JavaScript code is cross platform and the deployment does not require an app store.</p>
<p>As GWT generates JavaScript code I thought it would be suitable for packaging up as a mobile widget so as I have a Nokia phone I took the <a href="http://www.forum.nokia.com/Technology_Topics/Web_Technologies/Web_Runtime/" target="_blank">Nokia WRT kit</a> and gave it a go. The results were very promising and my test GWT app worked very well on my phone, a Nokia E72.</p>
<p>The problem is of course that you cannot use RPC calls as you don&#8217;t have a server. However you can use JSONP to talk to a remote server which is perfectly adequate and this works well so far too. Using GWT to produce mobile widgets seems to have a lot of potential for creating mobile apps very quickly and with little pain. It would be great to hear from anyone else who is using this approach for mobile apps and any problems they encountered that I haven&#8217;t yet.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bristol-gtug.org/?feed=rss2&amp;p=71</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Wave and Early Versions of Groove</title>
		<link>http://www.bristol-gtug.org/?p=65</link>
		<comments>http://www.bristol-gtug.org/?p=65#comments</comments>
		<pubDate>Wed, 07 Oct 2009 21:31:35 +0000</pubDate>
		<dc:creator>Daniel Vaughan</dc:creator>
				<category><![CDATA[Google Wave]]></category>
		<category><![CDATA[groove]]></category>

		<guid isPermaLink="false">http://www.bristol-gtug.org/?p=65</guid>
		<description><![CDATA[I was going to write an article about  Google Wave, what it is, whether it is something to get excited about or not etc. etc. However I would only be writing something that will have been written by others all over the web. If anyone has found some great &#8220;What it is and why to get excited&#8221; type articles please send me a link.
Google Wave has reminded me of a product I got very excited about before, a product which now is part of MS Office but one that ...]]></description>
			<content:encoded><![CDATA[<p>I was going to write an article about  Google Wave, what it is, whether it is something to get excited about or not etc. etc. However I would only be writing something that will have been written by others all over the web. If anyone has found some great &#8220;What it is and why to get excited&#8221; type articles please send me a link.</p>
<p>Google Wave has reminded me of a product I got very excited about before, a product which now is part of MS Office but one that rarely gets talked about; Groove. I thought I would look back and try to understand the reasons Groove did not become as big as I expected and see any of these reasons apply to Google Wave.</p>
<p>Groove was the idea of Ray Ozzie creator on Lotus Notes who founded Groove Networks in 1997.  The first beta was released in 2000 and as a Lotus Notes/Domino developer at the time working on collaboration software it certainly got my attention.</p>
<p>The idea of Groove was to create a system that enabled people inside and outside an organisation to collaborate on work together over the web. The idea was that it would make it easy for users to form virtual workgroups and start collaborating, communicating and sharing documents in real time very quickly and in a secure way.</p>
<p><img class="alignleft size-medium wp-image-68" title="groove" src="http://www.bristol-gtug.org/wp-content/uploads/2009/10/groove-300x214.png" alt="groove" width="300" height="214" />Early version of Groove had many of the features which would not look out of place in Google Wave. Groove had instant messaging that appeared as you typed and allowed real time collaborative editing of documents. It also had discussions and an interactive whiteboard and build in together with voice and video conferencing for example. It allowed developers to build their own plugin apps using an XML based language I never really understood. In 2001 this was something really impressive and I was sure that it was going to be big.</p>
<p>For me the best thing about it was that it had a peer to peer desktop client so each user had a full copy of the data that was synchronised with other users over the web and was available offline. There was no central server.</p>
<p>So why did Groove not take over the world? At the time I remember there were the following objections from businesses that prevented its takeup:</p>
<ul>
<li>Speed &#8211; the peer to peer model used XML messages to sync all changes which used a lot of network traffic. The client too was hugely resource intensive and even powerful PCs at the time were reduced to a crawl.</li>
<li>Managability- the lack of a central server meant that there was perceived to be no control of the data. How do you backup? How do you manage users etc. The &#8220;enterprise server&#8221; was a long time coming.</li>
<li>Client Installation &#8211; The client needed to be installed on the users PC and from what I remember setup was not straight forward.</li>
<li>Security &#8211; Businesses were put of by the P2P model. In 2001 people the only thing people thought about when they heard P2P was Napster and piracy. Bosses ran a mile from the idea of having their sensitive business data on a system that used P2P and not knowing how many copies of data there were and who had them was terrifying.</li>
<li>Timing &#8211; Groove was started in the dotcom boom but not released until the bubble had burst.</li>
<li>Price &#8211; you had to pay for it and it wasn&#8217;t that cheap. Businesses were suffering from a downturn and there wasn&#8217;t the money about for enterprises to make bug investments.</li>
<li>Developer Community Support &#8211; Groove was difficult to develop for (in my experience) and there was little help available.</li>
<li>Its was different &#8211; Groove was very different to most things which came before and so was a hard to explain the advantages of it.</li>
</ul>
<p>In many ways I see Google Wave as being similar to Groove in concept but do I think it will suffer from the same problems:</p>
<ul>
<li>Speed &#8211; NO &#8211; technology has moved on and other GWT applications are pretty quick in Chrome for example.</li>
<li>Manageabiliy &#8211; NO &#8211; from what I understand companies can run their own server if they want.</li>
<li>Client Installation &#8211; NO &#8211; web based.</li>
<li>Security &#8211; MAYBE &#8211; No P2P barrier but businesses will still need to (or believe they need to) trust Google with their data.</li>
<li>Timing &#8211; NO &#8211; in a recession again but Google are not asking people to pay for it.. yet.</li>
<li>Price &#8211; NO &#8211; I have not seen any enterprise pricing but believe it is free to start with.</li>
<li>Developer Community Support &#8211; NO &#8211; open apis, documentation, lots of interest from developers and familiar tools to develop with.</li>
<li>Its different &#8211; MAYBE &#8211; Things that are different will always be difficult to sell to enterprises however if people take to it in other parts of their life it will be interesting to introduce.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.bristol-gtug.org/?feed=rss2&amp;p=65</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using the Ext-GWT (GXT) MVC Framework</title>
		<link>http://www.bristol-gtug.org/?p=45</link>
		<comments>http://www.bristol-gtug.org/?p=45#comments</comments>
		<pubDate>Wed, 07 Oct 2009 10:43:27 +0000</pubDate>
		<dc:creator>Daniel Vaughan</dc:creator>
				<category><![CDATA[Ext-GWT (GXT)]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[GWT]]></category>
		<category><![CDATA[Home]]></category>
		<category><![CDATA[ext-gwt]]></category>
		<category><![CDATA[gxt]]></category>
		<category><![CDATA[overview]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.bristol-gtug.org/?p=45</guid>
		<description><![CDATA[In this article I try to give a brief tutorial of how to use the
GXT (Ext-GWT) MVC. Using GWT 1.7 and GXT 2.0.1.
Having worked out what was going on in GXT MVC I was able to put
together a simple sample app of my own. The example I choose was an app
to to retrieve and display the current stock price of Google. To keep things simple the backend is based on an example from the GreatWebGuy website.
The diagram below shows the key components used in the GXT MVC
framework and how they ...]]></description>
			<content:encoded><![CDATA[<p>In this article I try to give a brief tutorial of how to use the<br />
GXT (Ext-GWT) MVC. Using GWT 1.7 and GXT 2.0.1.</p>
<p>Having worked out what was going on in GXT MVC I was able to put<br />
together a simple sample app of my own. The example I choose was an app<br />
to to retrieve and display the current stock price of Google. To keep things simple the backend is based on an <a href="http://greatwebguy.com/programming/java/stock-quote-and-chart-from-yahoo-in-java/" target="_blank">example from the GreatWebGuy website</a>.</p>
<p>The diagram below shows the key components used in the GXT MVC<br />
framework and how they talk to each other:</p>
<h2><img class="alignleft size-full wp-image-46" title="gxtmvc" src="http://www.bristol-gtug.org/wp-content/uploads/2009/10/gxtmvc.png" alt="gxtmvc" width="200" height="435" />Events</h2>
<p>First I defined the events the application will use. These are defined<br />
in a class as static fields which are instances of the EventType class.</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> StockAppEvents<br />
<span style="color: #009900;">&#123;</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> EventType Init <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> EventType<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> EventType <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aerror+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Error</span></a> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> EventType<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> EventType StockPriceUpdated <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> EventType<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> EventType UIReady <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> EventType<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> EventType StockPriceUpdateRequested <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> EventType<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<h2>The Controller</h2>
<p>A controller is responsible for handling events. It registers to receive a notification from the dispatcher each time an event of a specified type occurs. It can then make changes to the model and/or forward the event on to the view it is responsible for in order to update the display for example.</p>
<p>Controllers register the events they are interested in their constructors. This is achieved by using the registerEventTypes method which takes an AppEvent as an argument.</p>
<p>For example if a controller was required to handle to perform an action when the StockPriceUpdated event occurred it would look like this:</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> StockPriceController <span style="color: #000000; font-weight: bold;">extends</span> Controller<br />
<span style="color: #009900;">&#123;</span><br />
...<br />
<span style="color: #000000; font-weight: bold;">public</span> StockPriceController<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
registerEventTypes<span style="color: #009900;">&#40;</span>StockAppEvents.<span style="color: #006633;">StockPriceUpdated</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
...<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>In order to be able to handle events a controller is required to implement the handleEvent method. This method defines how the controller processes an event notification received from the dispatcher.</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> StockPriceController <span style="color: #000000; font-weight: bold;">extends</span> Controller<br />
<span style="color: #009900;">&#123;</span><br />
...<br />
@Override<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> handleEvent<span style="color: #009900;">&#40;</span>AppEvent event<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
EventType eventType <span style="color: #339933;">=</span> event.<span style="color: #006633;">getType</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>eventType.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>StockAppEvents.<span style="color: #006633;">StockPriceUpdated</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
onStockDataUpdated<span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
...<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>You also need to specify the view that the controller is responsible for in order to be able to forward events to it. This is done in the initialise method.</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> StockPriceController <span style="color: #000000; font-weight: bold;">extends</span> Controller<br />
<span style="color: #009900;">&#123;</span><br />
...<br />
@Override<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> initialize<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
<span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">initialize</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
stockPriceView <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> StockPriceView<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
...<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>If a controller need to forward event onto the view for processing you can use the forwardToView method.</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> StockPriceController <span style="color: #000000; font-weight: bold;">extends</span> Controller<br />
<span style="color: #009900;">&#123;</span><br />
...<br />
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> onStockDataUpdated<span style="color: #009900;">&#40;</span>AppEvent event<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
forwardToView<span style="color: #009900;">&#40;</span>stockPriceView, event<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
...<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<h2>The View</h2>
<p>The view provides the interface with the user. It is responsible for displaying data and responding to user actions by creating events. When creating a view the view’s controller must be defined in its constructor.</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> StockPriceView <span style="color: #000000; font-weight: bold;">extends</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aview+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">View</span></a><br />
<span style="color: #009900;">&#123;</span><br />
<span style="color: #000000; font-weight: bold;">public</span> StockPriceView<span style="color: #009900;">&#40;</span>Controller controller<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
<span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>controller<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
...<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>It also is required to implement the handleEvents method in the same way as the controller.</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> StockPriceView <span style="color: #000000; font-weight: bold;">extends</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aview+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">View</span></a><br />
<span style="color: #009900;">&#123;</span><br />
...<br />
@Override<br />
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> handleEvent<span style="color: #009900;">&#40;</span>AppEvent event<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
EventType eventType <span style="color: #339933;">=</span> event.<span style="color: #006633;">getType</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>eventType.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>StockAppEvents.<span style="color: #006633;">StockPriceUpdated</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
onStockPriceUpdated<span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
...<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>The view does not communicate directly with its controller; instead it forwards events to the dispatcher by calling the static Dispatcher.forwardEvent method.</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> StockPricePortlet <span style="color: #000000; font-weight: bold;">extends</span> Portlet<br />
<span style="color: #009900;">&#123;</span><br />
...<br />
<span style="color: #000000; font-weight: bold;">public</span> StockPricePortlet<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
btnUpdate.<span style="color: #006633;">addSelectionListener</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> SelectionListener<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> componentSelected<span style="color: #009900;">&#40;</span>ButtonEvent ce<span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
Dispatcher.<span style="color: #006633;">forwardEvent</span><span style="color: #009900;">&#40;</span>StockAppEvents.<span style="color: #006633;">StockPriceUpdateRequested</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
...<br />
<span style="color: #009900;">&#125;</span><br />
...<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<h2>The Dispatcher</h2>
<p>The dispatcher is used to notify controllers that an event has occurred.</p>
<p>In order to receive any events a controller needs to first be registered with the dispatcher. This is achieved by adding a controller to the dispatcher using the addController method and would typically be done on module load.</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> StockApp <span style="color: #000000; font-weight: bold;">implements</span> EntryPoint<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onModuleLoad<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; ...<br />
&nbsp; &nbsp; <span style="color: #006633;">Dispatcher</span> dispatcher <span style="color: #339933;">=</span> Dispatcher.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; dispatcher.<span style="color: #006633;">addController</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> StockPriceController<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; ...<br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Similarly controllers can stop receiving events using the removeContoller method. A list of controllers currently registered with the dispatcher can be retrieved using the getControllers method.</p>
<p>In GXT the dispatcher is a singleton, that is only one instance of it exists in the application. In order to fire an event there are two options: The first is to retrieve the dispatcher instance using the static Dispatcher.get() static and then call the resultant dispatchers dispatch method. The alternative is to call the static Dispatcher.forwardEvent. Both methods do the same thing.</p>
<div class="codecolorer-container java default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> StockApp <span style="color: #000000; font-weight: bold;">implements</span> EntryPoint<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onModuleLoad<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><br />
&nbsp; <span style="color: #009900;">&#123;</span><br />
&nbsp; ...<br />
&nbsp; &nbsp; <span style="color: #006633;">dispatcher</span>.<span style="color: #006633;">dispatch</span><span style="color: #009900;">&#40;</span>StockAppEvents.<span style="color: #006633;">Init</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; ...<br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>The only difference I can see is that forwardEvent has a version that allows you to specify that an event is a history event. I personally favour using the static Dispatcher.forwardEvent version from views as it is more convenient.</p>
<p>When calling either the dispatch or forwardEvent methods the code makes sure that the controllers are properly initialized. It then notifies only the controllers that have specifically registered to receive events of that type (using the registerEventTypes in their constructor) that the event has occurred using the fireEvent method.</p>
<p>It is possible to call the fireEvent method directly however I cannot see any reason to use this over the forwardEvent or dispatch method. In this case all controllers would receive the event whether or not they had registered to receive events of that type.</p>
<h2>The Application</h2>
<p>I hope this gives you some idea of how to get started with a GXT MVC application.</p>
<p>The source code for my test application is available here:</p>
<p><a href="http://www.bristol-gtug.org/wp-content/uploads/2009/10/StockApp.zip" target="_blank">StockApp.zip (10Kb)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bristol-gtug.org/?feed=rss2&amp;p=45</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Google Wave Overview</title>
		<link>http://www.bristol-gtug.org/?p=38</link>
		<comments>http://www.bristol-gtug.org/?p=38#comments</comments>
		<pubDate>Mon, 05 Oct 2009 17:54:53 +0000</pubDate>
		<dc:creator>Daniel Vaughan</dc:creator>
				<category><![CDATA[Google Wave]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[overview]]></category>
		<category><![CDATA[wave]]></category>

		<guid isPermaLink="false">http://www.bristol-gtug.org/?p=38</guid>
		<description><![CDATA[I was searching around for a good written Google Wave overview rather than the 1h20m YouTube video and I found an excellent one at mashable. If anyone else has found anything better please let me know.
]]></description>
			<content:encoded><![CDATA[<p>I was searching around for a good written Google Wave overview rather than the 1h20m YouTube video and I found an excellent one at <a href="http://mashable.com/2009/05/28/google-wave-guide/" target="_blank">mashable</a>. If anyone else has found anything better please let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bristol-gtug.org/?feed=rss2&amp;p=38</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Welcome to Bristol-GTUG</title>
		<link>http://www.bristol-gtug.org/?p=8</link>
		<comments>http://www.bristol-gtug.org/?p=8#comments</comments>
		<pubDate>Sat, 12 Sep 2009 17:34:11 +0000</pubDate>
		<dc:creator>Daniel Vaughan</dc:creator>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[Headline]]></category>

		<guid isPermaLink="false">http://www.bristol-gtug.org/?p=8</guid>
		<description><![CDATA[Welcome to the website of the official Bristol Technology User group.
The Bristol GTUG is a non-profit developers group for anyone interested in or working with any of the Google Technologies.
The objective is to enable developers to share information, knowledge and experience with others both online and through regular meet-ups in the Bristol area.
If you have anything you would like to contribute be it information, best –practices, demonstrations of projects or have questions about any of the Google technologies please join us.
]]></description>
			<content:encoded><![CDATA[<p>Welcome to the website of the official Bristol Technology User group.</p>
<p>The Bristol GTUG is a non-profit developers group for anyone interested in or working with any of the Google Technologies.</p>
<p>The objective is to enable developers to share information, knowledge and experience with others both online and through regular meet-ups in the Bristol area.</p>
<p>If you have anything you would like to contribute be it information, best –practices, demonstrations of projects or have questions about any of the Google technologies please join us.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bristol-gtug.org/?feed=rss2&amp;p=8</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
