tag:blogger.com,1999:blog-38954748343443837092024-02-21T19:09:26.245-08:00GWT SushiRolls of GWT, Dart, Java, Spring, Grails, Design Patterns and other pro web development goodies.Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.comBlogger64125tag:blogger.com,1999:blog-3895474834344383709.post-39993056938698973632016-03-27T15:35:00.001-07:002016-03-27T15:35:19.990-07:00Is GWT Dead, Dying or Thriving?So I haven't written about GWT for several years, apologies. Apart from the birth of my new baby twin boys, (2 years ago) I haven't had much spare time, or frankly the inclination to write about GWT. Why? Well I am just not that enthused about the platform anymore. As a software engineer you are always conscious whether you are using the best tool for the job, it is on your mind constantly. You are constantly bombarded with forum discussions, technology posts, how-to videos, conferences, product releases. All building a narrative of what is the best and most current technology to use. A lot of these are gumpf, but some are enlightening. <br />
<br />
GWT used to enlightening. I was coming off 5 years of Microsoft development and I was wowed by the GWT SDK. It did so much. I could write client code in the same language as my server. It would compile to that horrid Javascript language for me and also take account of all browser differences. WOW. I had just about had it with IE. Internal thought GWT means never having to deal with IE again. Sign me up!<br />
<br />
GWT was good. It was refreshing. It was new. Google IO 2010 was all about GWT. The only Google IO I have ever been to was confirming all my suspicions about GWT. They built ADWORDS with it, for god sake. Google loves it. I love it. Lets jump in. And then it happened. I built something large with GWT. 9 minute compile time? Hmmmm.... ouch.<br />
<br />
For years we have been constantly reminded about how the compile time will speed up. About how it is constantly being adjusted and improved. Which is nice. It's nice to know that it's a problem for others. I guess maybe I should have been thankful for my 9 minute compile, as it could have been 20 minutes. <br />
<br />
The web moves fast and so does this engineer. I have been using Angular for the last 4 years and it is clear that the leap in productivity I experienced from moving to GWT from legacy web dev, has been achieved again by moving to Angular 1.XX and now Angular 2.XX. This will be the last post on GWT. I wish it all the best in the future and hope it rests in peace quickly. Goodbye GWT - You were briefly awesome.Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com17tag:blogger.com,1999:blog-3895474834344383709.post-32680083451836956732013-06-22T09:48:00.001-07:002013-06-22T09:48:25.614-07:00GWT-Tour - Awesome GWT guided tour functionality.GWT-Tour is a GWT library to make it easy for developers to add product tours to their pages. GWT-Tour accepts a Tour object as input and provides an API for the developer to control rendering the tour display and managing the tour progress.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqIX37KfUvEZGPLwRHeosmdJO7UBJnmM_lh14srgUIZ7ZAYFgdeKZ-xAkrOIGhkiKY_tu6nGv89v5sNRK39hXyM7yOyw5NFMxPyHjEbTqVez9MN0Jo4saqXhJ51uofJ4WJ4xviIINmjxE/s1600/Screen+Shot+2013-06-22+at+9.46.48+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqIX37KfUvEZGPLwRHeosmdJO7UBJnmM_lh14srgUIZ7ZAYFgdeKZ-xAkrOIGhkiKY_tu6nGv89v5sNRK39hXyM7yOyw5NFMxPyHjEbTqVez9MN0Jo4saqXhJ51uofJ4WJ4xviIINmjxE/s400/Screen+Shot+2013-06-22+at+9.46.48+AM.png" width="400" /></a></div>
<span id="goog_820226601"></span><span id="goog_820226602"></span><br />
Framework website - <a href="http://eemi2010.github.io/gwt-tour/">http://eemi2010.github.io/gwt-tour/</a>Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com3tag:blogger.com,1999:blog-3895474834344383709.post-73660515226365264352013-02-26T18:50:00.001-08:002013-02-26T18:50:11.754-08:00Dart with GWT<iframe allowfullscreen="" frameborder="0" height="270" src="http://www.youtube.com/embed/F33aPc5FjVo" width="480"></iframe>Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com2tag:blogger.com,1999:blog-3895474834344383709.post-35446031351889895802013-02-21T12:07:00.000-08:002013-02-22T07:20:46.987-08:005 Tips learned from building an large GWT application with ApptegicI should really start with an apology. For the past year or so I have been working at a fantastic startup and have really let my blog submissions slide. So to the three people that have been sitting on the edge of your seats, I apologize. <br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
So where have I been?<br />
<div style="text-align: center;">
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://www.apptegic.com/" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPDziW7yIM3dPP7aipMzl2SRYMkv0PR9ytgSXVsUKOqT9H1Rw2B10uoZaEkqSCcNREXnOYqvRW8RWzt7rAQyACrmUE6IwC1gEoD6oq946B-zK-s5UEeBVLELkl_Q42W2_QpprhuqbX6Ic/s1600/Apptegic.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">UNLOCK CUSTOMER USAGE DATA, DRIVE CUSTOMER SUCCESS<br /><a href="http://www.apptegic.com/">www.apptegic.com</a></td></tr>
</tbody></table>
</div>
In November 2011 I interviewed for a company called <a href="http://www.apptegic.com/">Apptegic</a>. A Boston based tech start-up that is helping businesses unlock their customer behavioral data to measure engagement and reduce churn. There is a lot to that last sentence so lets break it down. <br />
<br />
<b>Unlocking behavioral data</b> relates to how <a href="http://www.apptegic.com/">Apptegic</a> integrates with your site and leverages data so you can understand what your customers are doing. Using a customizable piece of javascript customer information is sent including user and account, coupled with any custom field key-value pair you want to record. This information is processed and using our analytics platform you can view what your customers are, and sometimes more importantly, are <b>not </b>doing. <br />
<br />
<b>Engagement </b>is a customizable measurement based on key data, such as visit, user performed actions, and business information. The measurement helps answer common key questions all web based businesses have: How engaged your users? How does this engagement change over time? Has engagement changed after releasing new features?<br />
<br />
<b>Reduce Churn: </b>A wise woman once said: "it is easier and more cost effective to retain a customer than to go find a new one". <a href="http://www.apptegic.com/">Apptegic</a> helps reduce churn by helping you understand what your customers are doing but also offers one distinct and important advantage. Behavioral based messaging. This is the killer feature, in my humble but biased opinion, whilst the user is in the application, and in real time, you can display messages based on their usage behavior. The traditional model is to analyze stats the next day, build an email campaign based on usage, then send out an email two days later. Ours is to collect metrics in real time, display <b>relevant</b> message whilst you are in the application, and increase your engagement with the product. By informing you with relevant information we can prevent you from losing that customer - churning.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYjWQTO5Kxx8kuAjV_mpjqBD2O2WGuEkoKRK2QE8UdXP1Z_WsLQmmcQbqwFR0eZHtgPOC8gsnYBE2mQRu-0nX2CmBt7Si7H_JjC_TnU9_SMsXvddor6WR0wUQU_KIDnZvXiG_I_KyIQ00/s1600/Screen+Shot+2013-02-21+at+10.19.09+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="274" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYjWQTO5Kxx8kuAjV_mpjqBD2O2WGuEkoKRK2QE8UdXP1Z_WsLQmmcQbqwFR0eZHtgPOC8gsnYBE2mQRu-0nX2CmBt7Si7H_JjC_TnU9_SMsXvddor6WR0wUQU_KIDnZvXiG_I_KyIQ00/s320/Screen+Shot+2013-02-21+at+10.19.09+AM.png" width="320" /></a></div>
<br />
<br />
<div style="text-align: center;">
<b><br /></b></div>
<div style="text-align: center;">
<b>Using Google Web Toolkit at <a href="http://www.apptegic.com/">Apptegic</a></b></div>
<div style="text-align: center;">
<br />
<div style="text-align: left;">
At <a href="http://www.apptegic.com/">Apptegic</a> we have built a large scalable application using common techniques recommended by the GWT community. Below are five tips that I would recommend to anyone building a large scale GWT application:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<b>Tip 1: Scalability built-in</b></div>
<div style="text-align: left;">
If you aren't using a design standard to build your application you are going to run into problems when you scale your application. You'll end up in a spaghetti highly-coupled mess. Believe me I have been there. For GWT I recommend GWTP. The guys over at GWTP are great. Over the past several years they have built a mature useful MVP implementation for GWT. I have used it on several products now and it just keeps getting better with time. I will leave their own marketing to help with the promotion. Grab the framework over at GitHub: <a href="https://github.com/ArcBees/GWTP">https://github.com/ArcBees/GWTP</a></div>
</div>
<br />
<b>Tip 2: Decouple, decouple, decouple</b><br />
Use the <b>Dependency Injection </b>design pattern<b>. </b>Separate all of your concerns into logical entities then when you need them inject them as a dependency via the constructor or autowiring a variable. For GWT the only choice is to use Google's GIN framework. If you know Spring DI it is the GWT client equivalent of @Autowired.<br />
<a href="http://code.google.com/p/google-gin/">http://code.google.com/p/google-gin/</a><br />
<br />
<b>Tip 3: Helping the UI</b><br />
<b>GWT Query </b>is basically a JQuery implementation for GWT. It has lots of helper methods for direct dom manipulation, binding events and animations. We found it to be great at writing succinct code that achieves a great deal. In addition it has an active plugin community which build various beautiful UI components. We use their draggable implementation and a fantastic looking combo box called GWT Chosen. Check out the GWT Chosen demo page its awesome. <br />
<br />
GWT Query: <a href="http://code.google.com/p/gwtquery/">http://code.google.com/p/gwtquery/</a><br />
<div>
GWT Query Plugins: <a href="http://code.google.com/p/gwtquery-plugins/">http://code.google.com/p/gwtquery-plugins/</a></div>
<div>
GWT Chosen: <a href="http://jdramaix.github.com/gwtchosen/">http://jdramaix.github.com/gwtchosen/</a></div>
<div>
<br /></div>
<div>
<b>Tip 4: Be careful when selecting Smart GWT</b></div>
<div>
I am am split on SmartGWT. The widgets that come with GWT are woefully short of being fully featured. With SmartGWT you get fully featured widgets that are more difficult to customize visually. The problem lies in being able to mix the two. It is well documented that mixing SmartGWT with regular GWT widgets is not supported and from experience is painfully difficult to achieve successfully. My guideline would be: If you are building an internal product that requires a full feature set but you don't want to customize visually; or perhaps you are trying to prototype an idea and wan't to get something up and running quickly; then go with SmartGWT. If however you want to build a customer facing beautiful SaaS application then I would use native GWT and pick certain SmartGWT widgets selectively.</div>
<div>
<br /></div>
<div>
<b>Tip 5: Build-in Customer Usage Analytics</b></div>
<div>
If you are building a customer facing website and you want to understand how your users are utilizing your product. Then build-in analytics from the ground-up. As I am biased I will of course be recommending our own product - <a href="http://www.apptegic.com/">Apptegic</a>. There are alternatives, so go check out the competition I am confident that you will like what <a href="http://www.apptegic.com/">Apptegic</a> is offering.</div>
<div style="text-align: center;">
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://www.apptegic.com/" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPDziW7yIM3dPP7aipMzl2SRYMkv0PR9ytgSXVsUKOqT9H1Rw2B10uoZaEkqSCcNREXnOYqvRW8RWzt7rAQyACrmUE6IwC1gEoD6oq946B-zK-s5UEeBVLELkl_Q42W2_QpprhuqbX6Ic/s1600/Apptegic.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">UNLOCK CUSTOMER USAGE DATA, DRIVE CUSTOMER SUCCESS</td></tr>
</tbody></table>
</div>Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com3tag:blogger.com,1999:blog-3895474834344383709.post-32228933466088931612012-08-25T07:46:00.000-07:002012-08-25T07:46:32.691-07:00CSS3 Transitions and Transforms with DartDart is the "new" web language for building concise, complex and professional applications. As an avid GWT fan this is probably where GWT is heading, so I feel a need to get-up-to-speed in this area. Experiment 1 - Try CSS Transitions and Transforms. See code below:<br />
<br />
<br />
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><span class="s1">#import</span><span class="s2">(</span>'dart:html'<span class="s2">);</span></span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;">num <span class="s3">rotatePos</span> = 0;</span></div>
<div class="p4">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><span class="s1">var</span><span class="s2"> </span>textElement<span class="s2">;</span></span></div>
<div class="p5">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;">var<span class="s2"> </span><span class="s3">moveMe</span><span class="s2"> = </span>false<span class="s2">;</span></span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><span class="s1">void</span> main() {</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><span class="s2"> </span><span class="s4">query</span><span class="s2">(</span>"#text"<span class="s2">).</span><span class="s3">text</span><span class="s2"> = </span>"Click me!"<span class="s2">;</span></span></div>
<div class="p4">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><span class="s2"> </span>textElement<span class="s2"> = </span><span class="s4">query</span><span class="s2">(</span><span class="s5">"#text"</span><span class="s2">);</span></span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> <span class="s4">query</span>(<span class="s5">"#text"</span>).on.click.add(<span class="s4">fadeOutElement</span>);</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> <span class="s4">query</span>(<span class="s5">"#text"</span>).on.doubleClick.add(<span class="s4">fadeInElement</span>);</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> <span class="s4">query</span>(<span class="s5">"#buttonMove"</span>).on.click.add(<span class="s4">moveElement</span>);</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> <span class="s4">query</span>(<span class="s5">"#buttonRotate"</span>).on.click.add(<span class="s4">rotateElement</span>);</span></div>
<div class="p6">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><span class="s2"> </span>query<span class="s2">(</span><span class="s5">"#buttonRotateAndMove"</span><span class="s2">).on.click.add(</span>rotateAndMoveElement<span class="s2">);</span></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;">}</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><span class="s1">void</span> rotateAndMoveElement(Event event) {</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> <span class="s3">rotatePos</span> += 360;</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> Element element = <span class="s3">textElement</span>;</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> </span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> String moveMeTransform = <span class="s4">getMoveMeTransform</span>();</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> element.<span class="s3">style</span>.transition = <span class="s5">"1s"</span>;</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> element.<span class="s3">style</span>.transform = <span class="s5">"</span>${moveMeTransform}<span class="s5"> rotate(</span>${<span class="s3">rotatePos</span>}<span class="s5">deg)"</span>;</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;">}</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><span class="s1">void</span> rotateElement(Event event) {</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> <span class="s3">rotatePos</span> += 360;</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> Element element = <span class="s3">textElement</span>;</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> element.<span class="s3">style</span>.transition = <span class="s5">"1s"</span>;</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> element.<span class="s3">style</span>.transform = <span class="s5">"rotate(</span>${<span class="s3">rotatePos</span>}<span class="s5">deg)"</span>;</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> </span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;">}</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><span class="s1">void</span> moveElement(Event event) {</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> <span class="s3">rotatePos</span> += 360;</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> Element element = <span class="s3">textElement</span>;</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> element.<span class="s3">style</span>.transition = <span class="s5">"1s"</span>;</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> element.<span class="s3">style</span>.transform = <span class="s4">getMoveMeTransform</span>();</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;">}</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><span class="s1">void</span> fadeOutElement(Event event) {</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> <span class="s3">rotatePos</span> += 360;</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> </span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> Element element = event.<span class="s3">srcElement</span>;</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> </span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> element.<span class="s3">style</span>.transition = <span class="s5">"1s"</span>;</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> element.<span class="s3">style</span>.opacity = <span class="s5">"0.2"</span>;</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> element.<span class="s3">style</span>.transformStyle = <span class="s5">"opacity(ease-in-out)"</span>;</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;">}</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><span class="s1">void</span> fadeInElement(Event event) {</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> <span class="s3">rotatePos</span> += 360;</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> Element element = event.<span class="s3">srcElement</span>;</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> element.<span class="s3">style</span>.transition = <span class="s5">"1s"</span>;</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> element.<span class="s3">style</span>.opacity = <span class="s5">"1"</span>;</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> element.<span class="s3">style</span>.transformStyle = <span class="s5">"opacity(ease-in-out)"</span>;</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;">}</span></div>
<div class="p2">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><br /></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;">String getMoveMeTransform() {</span></div>
<div class="p4">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><span class="s2"> </span>moveMe<span class="s2"> = !</span>moveMe<span class="s2">;</span></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> <span class="s1">if</span> (<span class="s3">moveMe</span>) {</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><span class="s2"> </span><span class="s1">return</span><span class="s2"> </span>"translate(-100px,0px)"<span class="s2">;</span></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> } <span class="s1">else</span> {</span></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"><span class="s2"> </span><span class="s1">return</span><span class="s2"> </span>"translate(100px,0px)"<span class="s2">;</span></span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;"> }</span></div>
<div class="p3">
<span style="font-family: Courier New, Courier, monospace; font-size: xx-small;">}</span></div>
<div class="p2">
<br /></div>
Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com0tag:blogger.com,1999:blog-3895474834344383709.post-86304758012871266522012-07-03T22:27:00.000-07:002012-07-03T22:28:25.471-07:00Dart and GWT Videos from Google IO 2012<div class="separator" style="clear: both; text-align: center;">
<b>Google I/O 2012 - Dart - A Modern Web Language</b></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/bsGgfUreyZw?feature=player_embedded' frameborder='0'></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<b>Migrating Code from GWT to Dart</b></div>
<div class="separator" style="clear: both; text-align: center;">
<object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://3.gvt0.com/vi/EvACKPBo_R8/0.jpg" height="266" width="320"><param name="movie" value="http://www.youtube.com/v/EvACKPBo_R8&fs=1&source=uds" /><param name="bgcolor" value="#FFFFFF" /><param name="allowFullScreen" value="true" /><embed width="320" height="266" src="http://www.youtube.com/v/EvACKPBo_R8&fs=1&source=uds" type="application/x-shockwave-flash" allowfullscreen="true"></embed></object></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<b>Putting the App Back into Web App - Web Programming with Dart</b></div>
<div class="separator" style="clear: both; text-align: center;">
<b><br /></b><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/YxogQGnMA9Y?feature=player_embedded' frameborder='0'></iframe></div>
<br />
<br />Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com1tag:blogger.com,1999:blog-3895474834344383709.post-89980028447232735792012-06-28T19:25:00.001-07:002012-07-03T22:21:50.000-07:00Google I/O 2012: Dart- A Modern Web Language (Video)<iframe allowfullscreen="" frameborder="0" height="240" src="http://www.youtube.com/embed/bsGgfUreyZw" width="425"></iframe>Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com0tag:blogger.com,1999:blog-3895474834344383709.post-35265411747755105422012-04-03T20:08:00.001-07:002012-04-03T20:08:12.780-07:00Collection of GWT BlogsInspired from this post on <a href="http://stackoverflow.com/questions/2308156/best-gwt-blogs/10004398#10004398" target="_blank">Stack Overflow</a>. Here is a list of alternative GWT blogs:<br />
<br />
<br />
<ul style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Arial, 'Liberation Sans', 'DejaVu Sans', sans-serif; font-size: 14px; line-height: 18px; list-style-image: initial; list-style-position: initial; margin-bottom: 1em; margin-left: 30px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; vertical-align: baseline;">
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://turbomanage.wordpress.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://turbomanage.wordpress.com</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://borglin.net/gwt-project" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://borglin.net/gwt-project</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://googlewebtoolkit.blogspot.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://googlewebtoolkit.blogspot.com/</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://www.ongwt.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://www.ongwt.com/</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://gwt-unofficial.blogspot.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;">http://gwt-unofficial.blogspot.com/</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://www.gwtapps.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://www.gwtapps.com/</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://gwtblog.mynumnum.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://gwtblog.mynumnum.com/</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://development.lombardi.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">Lomardi Development Blog</a> has excellent posts covering some rare, but very useful topics.</li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://timepedia.blogspot.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">Ray Cromwell's blog</a> is also worth checking out.</li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://timepedia.blogspot.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://timepedia.blogspot.com</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://www.gdevelop.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://www.gdevelop.com/</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://raibledesigns.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://raibledesigns.com</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://googletesting.blogspot.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://googletesting.blogspot.com</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://lemnik.wordpress.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://lemnik.wordpress.com</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://www.gwtnow.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://www.gwtnow.com</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://www.gwtsite.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://www.gwtsite.com</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://stuffthathappens.com/blog" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://stuffthathappens.com/blog</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://roberthanson.blogspot.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;">http://roberthanson.blogspot.com</a></li>
<li style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;"><a href="http://webcentersuite.blogspot.com/" rel="nofollow" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4a6b82; cursor: pointer; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;">http://webcentersuite.blogspot.com</a></li>
</ul>
<div style="text-align: left;">
<span style="font-family: Arial, 'Liberation Sans', 'DejaVu Sans', sans-serif;"><span style="font-size: 14px; line-height: 18px;"><br /></span></span></div>Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com1tag:blogger.com,1999:blog-3895474834344383709.post-30948294195464942192011-11-13T11:12:00.001-08:002011-11-13T11:38:06.563-08:00Subjective thoughts on best practice with GWT applications.<br />
<div class="separator" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;">
<a href="http://draft.blogger.com/"><span id="goog_316789841"></span><span id="goog_316789845"></span><span id="goog_316789851"></span><img border="0" height="145" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsIpllJ1YiHrh1_qGRh_yUx6oNyeDPF6KGMfi8rIAKOoEFo_Yxnd-mK4a4IjdXHwlYHg8wOMOzm66F_5wif5uWKTPqB7u-z78Fmf34NMQbl3hBNOCri6NswsWrV27o-1l82L13xRK2G1E/s400/Screen+Shot+2011-11-13+at+11.36.47+AM.png" width="400" /><span id="goog_316789852"></span></a><span id="goog_316789846"></span><span id="goog_316789842"></span></div>
<br />
If you have spent anytime with me you know I love GWT. But in my humble opinion there are ways to build web applications that still involve the gamut of javascript frameworks and bog-standard HTML5 and javascript. Through my vast and continued learning experience of GWT I am beginning to see it in its current guise as being great for building complex and large widgets embedded in a web environment that is built in a more traditional web application framework. Using the word tradition is kind of absurd in the web application design sphere because a tradition is established in a matter of months and then disposed for a new tradition within a couple of years. However we appear to be heading towards a path of convergence in how and the way we code. I recognise this as entirely subjective but for companies adopting GWT for the first time, experimenting with complex GWT widgets, then embedding them into their existing web applications is a great way to start on the GWT path. <br />
<br />
Model-View-Controller (MVC) and Model-View-Presenter (MVP) are becoming the de-facto design patterns for building desktop, web and mobile applications. Developers pay attention, if these are not on your resume, get them on there as fast as possible. You should not leave home without it. Many frameworks in almost every language develop according to this pattern. So whether you are using Ruby on Rails, Grails, GWT, Spring MVC, Backbone.js they all design their frameworks around this convention. GWT is a little late to the game with regards to this and so two additional frameworks have been around for a while which in my opinion currently offer a lot more features than the "Activities and Places" inbuilt infrastructure. These two frameworks are GWT-Platform and MVP4G. They are both on Google Code and both have extensive user collaboration and input. Developing outside of GWT in the standard HTML-CSS-JS arena backbone.js offers a Javascript implementation of MVC. I haven't used it as of yet but from the brief tutorials I have read it appears to be very easy to use.<br />
<br />
In a similar vein, Dependency Injection is also a must have. Design your code to interfaces and inject interfaces at runtime. This is achievable in GWT using Google GIN on the client and Google GUICE on the server. However my current overwhelming suggestion on the server is the Spring framework. If you are writing Java server code and not using Spring, you are probably writing lots of boilerplace bullshit. Stop it now!. My server side framework knowledge is limited so would love to hear from other developers on alternatives, but from what I have seen this is well adopted, supported and promoted in the media and job adverts. Spring is about more than Dependency Injection but this is at the core of the framework. If you want to develop modular, testable code then you need to use DI. <br />
<br />
Using the Facebook web site as an example lets look at how you might construct this from scratch. Some GWT developers will suggest that the whole site should be built in GWT. I disagree but more on that later. However I believe that you will have a more flexible and productive if you develop the complex parts of your web site in GWT and embed them into the website. So when looking at your newsfeed the complex box that controls updating your status etc might be a small GWT application but it is embedded in an AJAX-controlled feed panel table. The reason I think this? Unless your whole team consists of ninja, ex-Google GWT developers that worked on the ad-sense or ad-words interface, then you are going to experience delays in your project as you migrate your developers to a new way or working. By concentrating complexity in small manageable chunks you reduce your exposure to delays in your project.Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com1tag:blogger.com,1999:blog-3895474834344383709.post-24408573280334019322011-11-01T09:57:00.000-07:002011-11-01T09:58:43.066-07:00Single Sign On to Google Apps Marketplace with a Grails applicationHey, have you tried Grails? If you love Java and love Spring, you are going to adore Groovy on Grails (www.grails.org). Last week I decided to try out Groovy on Grails using the excellent free ebook located here: <a href="http://www.infoq.com/minibooks/grails-getting-started" target="_blank">free ebook - yes please</a>. The book took me two days to navigate through and if you have any experience in Ruby on Rails, you are going to love it. <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbud9ykhahThLcfQkLenzZ6L-2kr3uNRqFdiEpSd9Wz7GOf3rOnhcXyU5b5K2o-t6nP6ByZ2P8n_e82FoUjfbK05IkP82HSZavYj8ltne_6nFXQ9s_ISuE5-OyW88yO2kf-37eSAzwn3w/s1600/Screen+Shot+2011-11-01+at+9.04.38+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbud9ykhahThLcfQkLenzZ6L-2kr3uNRqFdiEpSd9Wz7GOf3rOnhcXyU5b5K2o-t6nP6ByZ2P8n_e82FoUjfbK05IkP82HSZavYj8ltne_6nFXQ9s_ISuE5-OyW88yO2kf-37eSAzwn3w/s400/Screen+Shot+2011-11-01+at+9.04.38+AM.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Grails applications are typically called Groovy on Grails. Groovy is the language and Grails is the utility that uses convention over configuration to build easily, web applications. I won't go into too much detail here as the book says it better than I can but it is well worth checking out.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<b>SSO - Google Apps Marketplace</b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
As usual I always try to do something "complicated" in order to test the validity and maturity of any framework. My usual test case is to try Single Sign On with the Google Apps Marketplace. Again I am not going to go into too much details on what that actually means but if you are a Google Apps user and you have installed a third party application it is a way of authenticating the user without having to ask them for their credentials. Since I build apps for the Google Apps Marketplace I have to ensure I can do this otherwise the framework itself won't be a good choice. In addition because I am not an OpenID expert and prefer to stand on the shoulders of giants, the ease at which this can be implemented and understood is very important to me. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Since Groovy is a superset and dynamic language and can basically use Java and Java dependencies and since I had already built a SSO solution in a Java-GWT application for www.contactpa.com, I figured this should be fairly simple. On the whole it was my biggest problem was understanding how Dependency Injection works with Grails / Groovy and how to include dependencies in my project.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
All code is available here on this <a href="https://github.com/thinkjones/SSO-with-Google-Apps-Marketplace-with-Grails" target="_blank">github repository</a>.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<b>What did I learn?</b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Here are the pitfalls and problems I overcame whilst building this project:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>Dependencies: </b>I love/hate Maven, I have enough power to know how to do something and resolve issues but not a complete mastery, I am a perfectionist, to really understand. Anyhow I recognise the power of Maven and love it otherwise. So my first question was how to include dependencies. Now I tried messing around with the project by mavenizing but this left me with a whole host of other issues which I couldn't understand. Mainly due to my lack of experience in Grails. So I decided to use the standard approach. On conf/BuildConfig.groovy there are several sections to add dependencies. Anyone with maven experience will understand this coding convention:</div>
<pre> dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
// runtime 'mysql:mysql-connector-java:5.1.13'
runtime 'mysql:mysql-connector-java:5.1.13'
compile group:'org.openid4java', name:'openid4java-consumer', version:'0.9.6'
compile group:'com.google', name:'step2-common', version:'1-SNAPSHOT'
compile group:'com.google', name:'step2-consumer', version:'1-SNAPSHOT'
compile group:'com.google.inject', name:'guice', version:'3.0'
compile group:'javax.servlet', name:'jstl', version:'1.2'
compile group:'org.apache.httpcomponents', name:'httpclient', version:'4.1'
compile (group:'org.openxri', name:'openxri-client', version:'1.2.1') { excludes([ group: 'org.slf4j', name: 'slf4j-jcl']) }
compile group:'org.jdom', name:'jdom', version:'1.1'
compile group:'com.google.collections', name:'google-collections', version:'1.0'
}
</pre>
<div>
<br /></div>
<div>
<b>Mapping the openid: </b>I created a controller called GAMOpenIdController which stands for Google Apps Marketplace OpenID. Using convention this would have mapped to a url:/GAMOpenId/OpenID where for clarity I would prefer it to look like this: url:/openid. This url is the one Google redirects you to to check a user exists and then to authenticate the application. In order to do this I had to add an entry into the UrlMappings.groovy configuration file:</div>
<div>
<br /></div>
<div>
<div class="p1">
"/openid"<span class="s1">(controller:</span>"GAMOpenId"<span class="s1">, action:</span>"openid"<span class="s1">)</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="p1">
<span class="s1"><b>Adding Java SSO Code: </b>This is one of the reasons Grails is so awesome. You can embed Java code in with your Groovy code. Awesome. So I copied my SSO helper code from my other application. This is largely based on the marketplace sample application <a href="http://code.google.com/googleapps/marketplace/tutorial_java.html" target="_blank">located here</a>.</span></div>
<div class="p1">
<span class="s1"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7T-efoZ9tD_DMXLOoeXVdFFOrWf6XSK5y4uhbNrph5GuGenli_9aiVcNH_hK5LcjzpKcWiSwNXgh2ArBvLNMK0hvq7WLLoGo3oosArSuqmBhbryyjbK4UDlUDnKIY6woOH2zi8qXkNWo/s1600/Screen+Shot+2011-11-01+at+9.21.42+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7T-efoZ9tD_DMXLOoeXVdFFOrWf6XSK5y4uhbNrph5GuGenli_9aiVcNH_hK5LcjzpKcWiSwNXgh2ArBvLNMK0hvq7WLLoGo3oosArSuqmBhbryyjbK4UDlUDnKIY6woOH2zi8qXkNWo/s1600/Screen+Shot+2011-11-01+at+9.21.42+AM.png" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I have modified this code slightly and will include a full copy of the grails application at the end of this article.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>Adding the Controller: </b>This was so easy. See the code at the end.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>Adding the service: </b>Services in Grails control the business logic so I added all the servlet code from the marketplace application in here, but modified for Groovy. See file contactpa.GoogleOpenIdAuthService.groovy. This then called the Java SSO Code listed above. I didn't really have a problem here but the final stage of authentication was failing. I fixed this in the method <span style="background-color: transparent;">getReceivingUrl(). It turns out when the server makes a call to another server, when the request is returned this is routed to a URL of the format: url:/</span><span style="background-color: transparent;">grails/GAMOpenId/openid.dispatch whereas for the receivingURL to be authenticated correctly it should read url:/</span><span style="background-color: transparent;">openid.</span></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>Don't edit applicationContext.xml: </b>One trap, coming from a Spring background was that I needed to add some DI Beans in my Spring configuration for the Java SSO stuff above. Instead of following Grails convention I decided to edit the applicationContext.xml, which you would ordinaarily do in a standard Spring app. However this gave me a whole host of unusual errors until I read that beans should be configured in a file called resources.xml. So in conf/spring/resources.xml I added my beans:</div>
</div>
<pre><div class="p1">
<span class="s1"><?</span><span class="s2">xml</span><span class="s3"> </span>version<span class="s3">=</span><span class="s4">"1.0"</span><span class="s3"> </span>encoding<span class="s3">=</span><span class="s4">"UTF-8"</span><span class="s1">?></span></div>
<div class="p2">
<span class="s1"><</span><span class="s2">beans</span><span class="s3"> </span><span class="s5">xmlns</span><span class="s3">=</span>"http://www.springframework.org/schema/beans"</div>
<div class="p2">
<span class="s3"><span class="Apple-tab-span"> </span></span><span class="s5">xmlns:util</span><span class="s3">=</span>"http://www.springframework.org/schema/util"<span class="s3"> </span><span class="s5">xmlns:xsi</span><span class="s3">=</span>"http://www.w3.org/2001/XMLSchema-instance"</div>
<div class="p2">
<span class="s3"><span class="Apple-tab-span"> </span></span><span class="s5">xmlns:context</span><span class="s3">=</span>"http://www.springframework.org/schema/context"</div>
<div class="p2">
<span class="s3"><span class="Apple-tab-span"> </span></span><span class="s5">xmlns:mvc</span><span class="s3">=</span>"http://www.springframework.org/schema/mvc"<span class="s3"> </span><span class="s5">xmlns:task</span><span class="s3">=</span>"http://www.springframework.org/schema/task"</div>
<div class="p2">
<span class="s3"><span class="Apple-tab-span"> </span></span><span class="s5">xmlns:p</span><span class="s3">=</span>"http://www.springframework.org/schema/p"</div>
<div class="p3">
</div>
<div class="p1">
<span class="s3"><span class="Apple-tab-span"> </span></span>xsi:schemaLocation<span class="s3">=</span><span class="s4">"</span></div>
<div class="p2">
<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>http://www.springframework.org/schema/beans <span class="Apple-tab-span"> </span>http://www.springframework.org/schema/beans/spring-beans-3.0.xsd</div>
<div class="p2">
<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>http://www.springframework.org/schema/util <span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>http://www.springframework.org/schema/util/spring-util-3.0.xsd</div>
<div class="p2">
<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>http://www.springframework.org/schema/context <span class="Apple-tab-span"> </span>http://www.springframework.org/schema/context/spring-context-3.0.xsd</div>
<div class="p2">
<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>http://www.springframework.org/schema/mvc <span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd</div>
<div class="p2">
<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>http://www.springframework.org/schema/task <span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>http://www.springframework.org/schema/task/spring-task-3.0.xsd"<span class="s1">></span></div>
<div class="p3">
</div>
<div class="p2">
<span class="s3"><span class="Apple-tab-span"> </span></span><span class="s1"><</span><span class="s2">bean</span><span class="s3"> </span><span class="s5">name</span><span class="s3">=</span>"consumerHelperFactory"<span class="s3"> </span><span class="s5">class</span><span class="s3">=</span>"contactpa.sso.ConsumerFactory"<span class="s3"> </span><span class="s1">/></span></div>
<div class="p3">
<span class="Apple-tab-span"> </span></div>
<div class="p2">
<span class="s3"><span class="Apple-tab-span"> </span></span><span class="s1"><</span><span class="s2">bean</span><span class="s3"> </span><span class="s5">name</span><span class="s3">=</span>"consumerHelper"<span class="s3"> </span><span class="s5">class</span><span class="s3">=</span>"com.google.step2.ConsumerHelper"<span class="s3"> </span><span class="s5">factory-method</span><span class="s3">=</span>"getConsumerHelper"</div>
<div class="p2">
<span class="s3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s5">factory-bean</span><span class="s3">=</span>"consumerHelperFactory"<span class="s3"> </span><span class="s1">/></span><span class="s3"> </span></div>
<div class="p3">
<span class="Apple-tab-span"> </span></div>
<div class="p2">
<span class="s3"><span class="Apple-tab-span"> </span></span><span class="s1"><</span><span class="s2">bean</span><span class="s3"> </span><span class="s5">name</span><span class="s3">=</span>"httpFetcher"<span class="s3"> </span><span class="s5">class</span><span class="s3">=</span>"com.google.step2.http.DefaultHttpFetcher"<span class="s3"> </span><span class="s1">/></span></div>
<div class="p3">
<span class="Apple-tab-span"> </span></div>
<div class="p2">
<span class="s3"><span class="Apple-tab-span"> </span></span><span class="s1"><</span><span class="s2">bean</span><span class="s3"> </span><span class="s5">name</span><span class="s3">=</span>"googleHostedHostMetaFetcher"</div>
<div class="p2">
<span class="s3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s5">class</span><span class="s3">=</span>"contactpa.sso.GoogleHostedHostMetaFetcher"<span class="s1">></span></div>
<div class="p2">
<span class="s3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s1"><</span><span class="s2">constructor-arg</span><span class="s3"> </span><span class="s5">index</span><span class="s3">=</span>"0"<span class="s3"> </span><span class="s5">ref</span><span class="s3">=</span>"httpFetcher"<span class="s3"> </span><span class="s1">/></span></div>
<div class="p4">
<span class="s3"><span class="Apple-tab-span"> </span></span><span class="s1"></</span>bean<span class="s1">></span></div>
<div class="p4">
<span class="s1"></</span>beans<span class="s1">></span></div>
</pre>
<br />
<div style="text-align: center;">
<b>Summary</b></div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: left;">
This has turned to be a bit of a mind dump as I navigate a new area in Java development, for me anyhow. Grails is a great natural progression for Java developers looking to get into dynamic programming and using a framework for convention over configuration. </div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
I have open sourced this project and it is available at git hub to analyse and comment on:</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
https://github.com/thinkjones/SSO-with-Google-Apps-Marketplace-with-Grails</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com1tag:blogger.com,1999:blog-3895474834344383709.post-6672892901286605602011-10-26T11:03:00.000-07:002011-10-26T11:03:56.202-07:00Hey fools I am on twitter - @gwtsushiWith reference to the title of this article: After recently completing the Steve Jobs' biography I am convinced that the best way to succeed is to be a brutally honest ass hole. It won't last long, films and books tend to affect me. Anyway readers I am trying to spruce up my twitter feed and I need three things:<br />
<br />
1. A good logo.<br />
2. Brilliant followers<br />
3. Good things to follow.<br />
<span style="background-color: transparent;"><br /></span><br />
<span style="background-color: transparent;">Feel free to help, suggest or get in contact: </span><a href="http://twitter.com/#!/gwtsushi" style="background-color: transparent;">@gwtsushi </a><span style="background-color: transparent;">. </span><br />
<br />Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com0tag:blogger.com,1999:blog-3895474834344383709.post-79256374761511205372011-09-06T08:12:00.000-07:002011-09-06T08:12:15.286-07:00Spring Roo 1.2.0 with GWT and Google App EngineI was first introduced to Spring Roo at Google IO 2010 and I was amazed with the product, it allowed a developer to prototype an application very quickly, building everything from the server, domain, and GWT client. It looked awesome. <br />
<br />
When I got home I realised that we were shown a fixed demo in that many of the features didn't really work when building on Google App Engine and Google Web Toolkit. Not a problem as all developers know we are used to living on the cutting alpha-beta edge of software where great new features come with one huge caveat, they occasionally don't work.<br />
<br />
That was then and this is now. Like Sushi which I try every 6 months just to confirm that I still am not a huge fan, it doesn't taste of anything right?, I try the latest version of Spring Roo. <br />
<br />
<b>The Upgrade Path</b><br />
Let me just say that I love SpringSource they provide a lot of excellent tools for the Java developer and the Spring Roo documentation is no exception. The upgrade path is very easy, unpack the latest Spring Roo to a directory of your choosing, amend your $ROO_HOME variable in .profile (Mac OSx) and then re-establish the symbolic link to the roo command line. (<span style="background-color: white; font-family: monospace; font-size: 12px; text-align: justify;">sudo ln -s $ROO_HOME/bin/roo.sh /usr/bin/roo</span>)<br />
<br />
Done and done!<br />
<br />
<b>The Bleeding Edge</b><br />
So I tried Spring Roo 1.1.5 and it was giving me lots of errors with trying a GWT-GAE project. It seemed as equally unreliable as I had tried with previous versions. Let me just add if you are using a standard database such as MySQL or any of the other persistence options, I believe Spring Roo works just fine. The problems I usually run into are related to the peculiarities of Google App Engine and how Roo handles those. <br />
<br />
Since most of my current projects are currently in the GAE-GWT sphere and Roo advertises that it is suppose to work in this area, I decided to upgrade to the very latest Spring Roo, so I delved into the nightly builds and installed (1.2.0.BUILD-SNAPSHOT [rev 176e407]).<br />
<br />
<b>Go for 1.2.0 Its Much Better</b><br />
After building a couple of projects with 1.2.0 I can honestly say this is the best version yet by far. Why? Well it appears to work this time for GWT-GAE projects. Most of my personal work is done on Google App Engine. This might change as I am not really liking the new billing restrictions but we will see how those actually plan out when implemented.<br />
<br />
I typically build small projects that utilise some sort of reference between domain objects and then build a GWT project and then test it to see if it actually works. I will deal with deployment in a different post. What is great about Roo is that you can amend say the domain objects and the auto UI will get updated automatically. Simply add the line : private String userName; : to your domain object, boot up Roo and it auto creates the UI amendments needed. Pretty stunning. I haven't yet got to work out how you prevent it from doing this should you want to improve the UI, but I am sure that will come soon.<br />
<br />
The project I have built it is that for a taxi company to take bookings. It includes three domain objects Contact, Booking and Journey. A booking can have one or more contacts, and one ore more journeys. <br />
<br />
<b>A Spring Roo GAE GWT project that works</b><br />
Here is the contents of my Roo file, hopefully this will help you work with your project.<br />
<br />
<pre>project com.prestige.booking
persistence setup --provider DATANUCLEUS --database GOOGLE_APP_ENGINE --applicationId PrestigeBooking
enum type --class ~.shared.domain.ContactType
enum constant --name Booking
enum constant --name Billing
enum constant --name Passenger
entity --class ~.shared.domain.Contact --testAutomatically
field string --fieldName fullName --notNull
field string --fieldName email
field string --fieldName phoneNumber
field enum --fieldName contactType --type ~.shared.domain.ContactType
entity --class ~.shared.domain.Booking --testAutomatically
field reference --type ~.shared.domain.Contact passenger
entity --class com.prestige.booking.shared.domain.Journey --testAutomatically
field date --fieldName journeyDate --type java.util.Date
field string --fieldName startAddress
field string --fieldName endAddress
field string --fieldName startTime
field reference --fieldName booking --type com.prestige.booking.shared.domain.Booking
loggin setup --level INFO
web gwt setup
</pre>
<b><br /></b><br />
<b>Next Steps</b><br />
If you have used Roo or have done some interesting things with a Roo project please get in contact. I have yet to explore the AddOns or detailed more information on the workflow in a Roo project that goes from prototyping to real world application. Get in contact and lets document some Best Practices for this awesome product.Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com1tag:blogger.com,1999:blog-3895474834344383709.post-72844235447936321422011-09-02T07:43:00.000-07:002011-09-06T14:14:17.149-07:00Including external dependencies in your Maven GWT projectThere are many variations on this problem but lets relate it to a concrete example. Say perhaps you have a series of domain objects that exist in a dependency jar, but you want to be able to serialize them and send them to the GWT client. How do you serialize an object that doesn't already exist in your core GWT project?<br />
<br />
There are several steps required so lets take them in a logical order. <br />
<br />
<b>Step 1 : Ensure your objects are serializable</b><br />
Two things required here:<br />
<br />
<ul>
<li>Ensure your objects are implementing serializable.</li>
<li>Ensure you have at least a no-argument private constructor.</li>
</ul>
<div>
If you don't do these things your objects cannot be serialized and sent to the client.</div>
<div>
<br /></div>
<div>
<b>Step 2 : Add a GWT Module XML File</b></div>
<div>
In order to indicate to the GWT Compiler that this dependency is a GWT Compilable you need to tell it so. Therefore you will need to add the <ModuleName>.gwt.xml file in the /src/main/resources folder of the external dependency.</div>
<div>
<br /></div>
<div>
<pre class="prettyprint"><div class="p1">
<span class="s1"><?</span><span class="s2">xml</span><span class="s3"> </span>version<span class="s3">=</span><span class="s4">"1.0"</span><span class="s3"> </span>encoding<span class="s3">=</span><span class="s4">"UTF-8"</span><span class="s1">?></span></div>
<div class="p2">
<span class="s1"><</span><span class="s2">module</span><span class="s3"> </span><span class="s5">rename-to</span><span class="s3">=</span>"DependencyApi"<span class="s1">></span></div>
<div class="p3">
</div>
<div class="p2">
<span class="s3"> </span><span class="s1"><</span><span class="s2">inherits</span><span class="s3"> </span><span class="s5">name</span><span class="s3">=</span>"com.google.gwt.user.User"<span class="s1">/></span></div>
<div class="p2">
<span class="s3"> </span><span class="s1"><</span><span class="s2">source</span><span class="s3"> </span><span class="s5">path</span><span class="s3">=</span>"domainobjects"<span class="s3"> </span><span class="s1">/></span></div>
<div class="p3">
</div>
<div class="p4">
<span class="s1"></</span>module<span class="s1">></span></div>
</pre>
</div>
<div>
<br /></div>
<div>
In the above example "domainobjects" is the root package that you want serialized. Similar to how a lot of GWT projects are constructed where you see a client and shared entry.</div>
<div>
<br /></div>
<div>
<b>Step 3 : Export the dependency source</b></div>
<div>
In order for the GWT-Compiler to compile to javascript it needs access to the source files, therefore as part of the dependencies build process you need to tell it to export the source. An entry similar to the one below in your pom file should do it.</div>
<pre class="prettyprint"><div>
</div>
<div>
<div class="p1">
<span class="s1"><</span>build<span class="s1">></span></div>
<div class="p1">
<span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s1"><</span>plugins<span class="s1">></span></div>
<div class="p1">
<span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s1"><</span>plugin<span class="s1">></span></div>
<div class="p2">
<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s1"><</span><span class="s3">groupId</span><span class="s1">></span>org.apache.maven.plugins<span class="s1"></</span><span class="s3">groupId</span><span class="s1">></span></div>
<div class="p2">
<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s1"><</span><span class="s3">artifactId</span><span class="s1">></span><span class="s4">maven</span>-source-<span class="s4">plugin</span><span class="s1"></</span><span class="s3">artifactId</span><span class="s1">></span></div>
<div class="p1">
<span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s1"><</span>version<span class="s1">></span><span class="s2">2.1.2</span><span class="s1"></</span>version<span class="s1">></span></div>
<div class="p1">
<span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s1"><</span>executions<span class="s1">></span></div>
<div class="p1">
<span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s1"><</span>execution<span class="s1">></span></div>
<div class="p2">
<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s1"><</span><span class="s3">id</span><span class="s1">></span>attach-sources<span class="s1"></</span><span class="s3">id</span><span class="s1">></span></div>
<div class="p2">
<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s1"><</span><span class="s3">goals</span><span class="s1">></span></div>
<div class="p2">
<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s1"><</span><span class="s3">goal</span><span class="s1">></span>jar<span class="s1"></</span><span class="s3">goal</span><span class="s1">></span></div>
<div class="p2">
<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s1"></</span><span class="s3">goals</span><span class="s1">></span></div>
<div class="p1">
<span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s1"></</span>execution<span class="s1">></span></div>
<div class="p1">
<span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s1"></</span>executions<span class="s1">></span></div>
<div class="p1">
<span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s1"></</span>plugin<span class="s1">></span></div>
<div class="p1">
<span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span><span class="s1"></</span>plugins<span class="s1">></span></div>
<div class="p1">
<span class="s2"><span class="Apple-tab-span"> </span></span><span class="s1"></</span>build<span class="s1">></span></div>
</div>
<div>
</div>
<div>
</div>
</pre>
<b>Step 4 : Tell the GWT Compiler to add this dependency to the GWT Compile process</b>
<br />
<div>
In the main GWT Project's pom file you need to tell it to now use this dependency and combine its source into the compilation process. This is achieved using the GWT-Maven-Plugin's configuration section.</div>
<pre class="prettyprint"><div>
</div>
<div>
<div class="p1">
<span class="s1"><</span>configuration<span class="s1">></span></div>
<div class="p1">
<span class="s2"> <span class="Apple-tab-span"> </span></span><span class="s1"><</span>compileSourcesArtifacts<span class="s1">></span></div>
<div class="p2">
<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s1"><</span><span class="s3">artifact</span><span class="s1">><group id>:<artifactid></span><span class="s1"></</span><span class="s3">artifact</span><span class="s1">></span></div>
<div class="p1">
<span class="s2"> <span class="Apple-tab-span"> </span></span><span class="s1"></</span>compileSourcesArtifacts<span class="s1">></span></div>
</div>
<div>
<span class="s1"></</span>configuration<span class="s1">></span></div>
<div>
</div>
</pre>
<pre class="prettyprint"><b style="font-family: Times; white-space: normal;">Step 5: Include reference in the main Web Application Module.gwt.xml</b></pre>
<pre class="prettyprint"><span style="font-family: Times; white-space: normal;">Ensure you have a reference to the dependency in your main GWT Application config file.</span></pre>
<pre class="prettyprint"><div class="p1">
<span class="s1"> </span><!-- Dependency API --></div>
<div class="p2">
<span class="s1"> </span><span class="s3"><</span><span class="s4">inherits</span><span class="s1"> </span><span class="s5">name</span><span class="s1">=</span>'com.acme.com.DependencyApi'<span class="s1"> </span><span class="s3">/></span></div>
</pre>
<pre class="prettyprint"><b style="font-family: Times; white-space: normal;">Summary</b></pre>
<div>
Et Voila. That is it complete. A logical but not completely obvious solution to intermediate Maven users like myself. I would love to hear from the community how they might have solved this problem.</div>
<div>
<br /></div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com5Seattle, WA, USA47.6062095 -122.332070847.43492 -122.64792779999999 47.777499 -122.0162138tag:blogger.com,1999:blog-3895474834344383709.post-55680843414167628352011-07-25T17:03:00.000-07:002011-07-25T17:03:59.892-07:00Do you need a Java GWT developer?This is an open post to anyone that may require a GWT / Java Developer. I am the author of this blog and am currently looking for work either in a telecommute role or based in my hometown of the sunny Seattle, Washington. <br />
<br />
I have over 10 years development experience and have worked for a wide variety of institutions large and small. I enjoy working in Agile teams and adopting a test driven methodology. Having said that I am an expert at fitting into any team and have great references.<br />
<br />
If you know of anyone that needs a GWT developer, please get in touch.<br />
<br />
Regards<br />
GeneAnonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com3tag:blogger.com,1999:blog-3895474834344383709.post-83003618307424862602011-05-13T13:37:00.001-07:002011-05-16T18:37:12.428-07:00XML to POJO Mapper for GWT using a GDATA Example with Google Contacts (ContactEntry).<iframe align="left" frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=gwtsu-20&o=1&p=8&l=bpl&asins=1590597060&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr" style="align: left; height: 245px; padding-right: 10px; padding-top: 5px; width: 131px;"></iframe>If your like me I dislike cowboy coding. You are hacking away at something to get the job done, but the nagging thought at the back of your head is telling you "You kow you shouldn't be doing this". The best path maybe unavailable because a lack of experience, or perhaps we are unaware of suitable boilerplate-removing framework. We've all been there time is in the essence, deadlines are pressing and your new TPS Reports Engine needs to be delivered yesterday. Well I found myself in such a quandry recently and found a tool which will solve a common problem for many GWT developers. So instead of waffling what actually is the problem?<br />
<br />
Imagine an application that communicates with Google Contacts. Server-side you receive a an atom-rss feed representation of a contact in the form of a ContactEntry object. Google kindly provides you with GData POJOs which are already populated with the information you require. On the server this is beautiful, Google has done all the hard work and the POJO is populated with data. If you were using the wonderful Spring MVC you could render the contact information very easily. However you are a profound, if not magical developer that has the GWT Swiss army knife in their toolkit, and you want to send this POJO to the client. In the words of Mr. J. Carrey you reach the Alrighty Then brick wall of stoppage. The ContactEntry POJO is not serializable to the client. Or is it?<br />
<br />
One giant caveat is that I maybe encountering a newbie problem and someone may have created an easy way to make GData objects serializable for sending over GWT-RPC, but at present the only way I have found to do it, is manually, i.e. boilerplatery. Create my own ContactEntry objects on the server and populate them. This obviously involves copious amounts of repetition. It can be done this way, and is the way I have done it in the past, before I knew better, but it isn't efficient. <br />
<br />
Lets recap: We want a solution to send a GData ContactEntry object to the GWT client that we can use in a POJO, without becoming America's best plumber to create all the additional boilerplate code.<br />
<br />
My proposed solution: Send the XML as a String to the client and use a fancy GWT plugin, Piriti, XPath to auto populate a client side POJO. Quick, efficient and maintainable. So how do we do this?<br />
<br />
<b>Caveat: If someone has a better way of doing this please let me know. I am all ears. This may not be the best solution and I would love to know how anyone else has tackled this issue.</b><br />
<br />
<b>Step 1: Extract XML</b><br />
Lets assume you know how to get the ContactEntry from Google using their GData library but now you want to convert that into XML to transport to the GWT Client:<br />
<pre class="prettyprint">public String getContactEntryXml(ContactEntry entry) {
StringWriter sw = new StringWriter();
String entryXml = "";
try {
XmlWriter xw = new XmlWriter(sw);
entry.generate(xw, contactServiceFactory.getBasicContactsService().getExtensionProfile());
entryXml = sw.toString();
} catch (IOException e) {
e.printStackTrace();
}
return entryXml; // sw.toString();
}
</pre><b>Step 2: Transfer to Client</b><br />
I am assuming you know how to write GWT applications and communicate back and forther between the server and client. There are man built in libraries to do this, GWT RPC, Request Factory, and may external third party modules; net.customware.gwt.dispatch, GWTP etc.<br />
<b>Step 3: Create POJO</b><br />
The key here is reaally the library we are going to use. After looking at many examples I am using Piriti's library. It appears to be well used and has good documentation: <a href="http://code.google.com/p/piriti/" title="http://code.google.com/p/piriti/">http://code.google.com/p/piriti/</a><br />
<blockquote>Piriti (<a href="http://www.maoridictionary.co.nz/index.cfm?dictionaryKeywords=bridge" rel="nofollow">Maori for "bridge"</a>) is a JSON and XML mapper for GWT based on annotations and deferred binding. The following code snippets show the basic idea behind Piriti. </blockquote>So create a POJO and add these lines to the top of your POJO class:<br />
<pre class="prettyprint">public class ContactEntrySoho {
public static interface ContactEntrySohoReader extends XmlReader { }
public static final ContactEntrySohoReader XML = GWT.create(ContactEntrySohoReader.class);
</pre>These lines are used when mapping the POJO members to their XML nodes.<br />
<b>Step 4 : Map atom:title to an instance member</b><br />
Let's start easy lets map the atom:title entry of the ContactEntry XML. First it is probably worth taking a look a the XML:<br />
<pre class="prettyprint"><atom:title type='text'>Alan UserA1</atom:title>
</pre>Now lets look at how we would map this using XPath in the Pojo:<br />
<pre class="prettyprint">@Path("atom:title") private String title;
</pre>For a more in-depth view of XPath look online for various cheat-sheets and tutorials it is very powerful and very useful.<br />
<b>Step 5 : Load the Pojo</b><br />
All we need to do now is load the POJO with information to do this see the below:<br />
<pre class="prettyprint">@Override
public ContactEntrySoho parse(String xml) {
try {
Map<String, String> namespaces = new HashMap<String, String>();
namespaces.put("atom", "http://www.w3.org/2005/Atom");
namespaces.put("gContact", "http://schemas.google.com/contact/2008");
namespaces.put("batch", "http://schemas.google.com/gdata/batch");
namespaces.put("gd", "http://schemas.google.com/g/2005");
Document doc = new XmlParser().parse(xml, namespaces);
//Document doc = new XmlParser().parse(xml, NAMESPACES);
ContactEntrySoho sContactEntry = ContactEntrySoho.XML.read(doc);
return sContactEntry;
} catch (Exception e) {
return null;
}
}
</pre>The namespaces tell the parser what the tag mean and correspond to the root note elements of the ContactEntry XML:<br />
<pre class="prettyprint"><atom:entry xmlns:atom='http://www.w3.org/2005/Atom'
xmlns:gContact='http://schemas.google.com/contact/2008'
xmlns:batch='http://schemas.google.com/gdata/batch'
xmlns:gd='http://schemas.google.com/g/2005'>
</pre>Remember those additions we added to the POJO we simply call those (XML.read) to parse the xml Document. Et Voila! You have your own POJO created with hatever components from the XML you require.<br />
<b>Step 6 : A more complex example please sir.</b><br />
As you can see I have chosen the easiest node to map and as all articles which only go into the most basic of examples infuriate me, I shan't do the same here. Let's take a look at an example where we need to map to another POJO. Take the StructuredPostalAddress component of the ContactEntry class.<br />
The XML in ContactEntry:<br />
<pre class="prettyprint"><gd:structuredPostalAddress primary='false' rel='http://schemas.google.com/g/2005#home'>
<gd:formattedAddress>6217 Woodlawn Ave N, Seattle, WA. 98103</gd:formattedAddress>
<gd:street>1234 Acme Ave N</gd:street>
<gd:postcode>11111</gd:postcode>
<gd:city>Seattle</gd:city>
<gd:region>WA.</gd:region>
</gd:structuredPostalAddress>
</pre>The data in our parent ContactEntrySoho class:<br />
<pre class="prettyprint">@Path("//gd:structuredPostalAddress") private List<GDStructuredPostalAddress> gdStructuredPostalAddresses;
</pre>Wait what is GDStructuredPostalAddress? This is another POJO with the headers defined in Step 3.<br />
<pre class="prettyprint">public class GDStructuredPostalAddress extends ABaseElement{
public interface GDStructuredPostalAddressXmlReader extends XmlReader<GDStructuredPostalAddress> {}
public static final GDStructuredPostalAddressXmlReader XML = GWT.create(GDStructuredPostalAddressXmlReader.class);
@Path("gd:formattedAddress") private String formattedAddress;
@Path("gd:street") private String street;
@Path("gd:postcode") private String postcode;
@Path("gd:city") private String city;
@Path("gd:region") private String region;
</pre>Et Voila! I found when using this that the POJO members sometimes had to be public otherwise they wouldn't populate but this problem was intermittent, so I am unsure whether this is an issue with Piriti's excellent XML->POJO Mapper or my inept code ;).<br />
I would love to hear how other people are doing this as this seems like a good solution but I am sure there are many others.Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com4tag:blogger.com,1999:blog-3895474834344383709.post-83911969277734998542011-03-10T09:09:00.001-08:002011-03-10T09:11:05.548-08:00Excellent GIT Cheat Sheet<p>If your like me and fairly new to Git but appreciate its awesomeness. I have just found a great cheat sheet for GIT. Both clear, logical and concise get the sheet here: <a href="http://cheat.errtheblog.com/s/git/">Your link text here.</a></p><p>This website appears to be a collection of clear cheat sheets so go fill your boots people!</p>Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com0tag:blogger.com,1999:blog-3895474834344383709.post-1755101680056126452011-03-07T13:32:00.000-08:002011-03-07T13:32:58.975-08:00Jumpstart your GWT Development with JappStartI am currently experimenting with the JappStart framework, well not really a framework, but a beginner project that integrates many interesting technologies, all of which have been nicely converted and are ready to perform on Google App Engine. It has many features including:<br />
<span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-family: arial, sans-serif; font-size: 13px;"></span><br />
<ul style="max-width: 65em; padding-left: 40px;"><li>Appstats Support</li>
<li>Google AJAX Library API (jQuery)</li>
<li>Gravatar Integration</li>
<li>JRebel Support</li>
<li>Local Development Console Support (<a href="http://localhost:8080/_ah/admin" rel="nofollow" style="color: #0000cc;">http://localhost:8080/_ah/admin</a>)</li>
<li>Maven Support</li>
<ul style="max-width: 65em; padding-left: 40px;"><li>CSS/JS minification via the yuicompressor-maven-plugin</li>
<li>Uses the maven-gae-plugin</li>
</ul><li>Remote API/Bulk Loader Support</li>
<li>Sitemesh Integration</li>
<li>Spring 3</li>
<ul style="max-width: 65em; padding-left: 40px;"><li>JPA support</li>
<li>JSON/AJAX integration (Jackson)</li>
<li>JSR-303 validation</li>
<li>Localization support</li>
</ul><li>Spring Security 3</li>
<ul style="max-width: 65em; padding-left: 40px;"><li>Authentication</li>
<li>Expression based access control</li>
<li>Fully integrated with the App Engine Datastore and Memcache</li>
<li>Login/create account functionality with e-mail confirmation</li>
<li>Remember Me</li>
<li>Support for hierarchical roles</li>
</ul><li>Static Error Handler Support</li>
<li>Task Queue Support</li>
<li>URL Rewrite Integration</li>
</ul><br />
Current versions:<br />
<ul style="max-width: 65em; padding-left: 40px;"><li>Goole App Engine SDK for Java 1.4.2</li>
<li>jQuery 1.5.0</li>
<li>Maven GAE Plugin 0.8.2</li>
<li>Spring 3.0.5</li>
<li>Spring Security 3.0.5</li>
</ul><br />
As you can see it covers a lot of bases so you can get started easily on developing professional Google App Engine applications. I am examining it so I can also integrate GWT and MVP. Stay tuned for a demo project coming soon.<br />
<div><br />
</div><div>JappStart Home Page: <a href="http://code.google.com/p/jappstart/">http://code.google.com/p/jappstart/</a></div>Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com2tag:blogger.com,1999:blog-3895474834344383709.post-33538657108677944912011-01-25T14:22:00.000-08:002011-01-25T14:22:38.901-08:00Google I/O 2011Google IO 2011 Site is up and running. If your going and want to hook up please let me know.<br /><a href="http://www.google.com/events/io/2011/about.html">Google I/O 2011</a>Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com1tag:blogger.com,1999:blog-3895474834344383709.post-76217156809265569382011-01-24T20:53:00.000-08:002011-01-24T20:56:38.261-08:00Using Gin-Guice With Java Generics (Cell Table/DAO Example)Last year was so interesting and I have discovered so many interesting methods, ideas, patterns, and frameworks for developing professional software. A big proportion of this learning curve has been embracing Test-Driven Development and the necessary changes required to the structure of your code. One design pattern is the Dependency-Injection (DI) pattern where an objects dependencies are injected into the constructor. This allows us to clearly see what the dependencies of an object are, and using a framework allows us to inject our implemented classes. Spring offers a DI framework, which I hope to experiment at some point, but for now, and because many of the Google GWT examples use it, I am using Google GIN on the client side GWT projects and Google GUICE on the server.<br />
<br />
Explaining Generics is a little more complicated and I defer to someone more experienced. So a quick web search yields this:<br />
<blockquote><i>"Generics provides a way for you to communicate the type of a collection to the compiler, so that it can be checked. Once the compiler knows the element type of the collection, the compiler can check that you have used the collection consistently and can insert the correct casts on values being taken out of the collection."</i></blockquote>Now here comes the tricky part. <b>How do we inject a generic type class using Gin/Guice?</b><br />
<br />
<b></b>I always like to lead by example so lets talk about the example used here. Imagine you have a base class for all of your tables you are gong to render. However depending on the annotation used where you inject the base table, then that dictates what the type of the generic class used. In addition the annotation decides what ColumnFormatter class is used to render table. So in summary:<br />
<ul><li>1 Base Class SohoTable<T></li>
<li>Several ColumnFormatter classes depending on table used.</li>
</ul><b>Declaration of SohoTable</b><br />
<pre class="prettyprint">public class SohoTable<T extends HasReadId> extends Composite implements
HasEventBus, HasTableChangedEventHandler {
</pre><pre class="prettyprint">@Inject
public SohoTable(ColumnFormatter columnFormatter) {
</pre><br />
Here the base class shows the generics declaration. Here you can replace HasReadId with any interface your common DAOs implement. For simplicity we just ensure that HasReadId has a method to get the unique Id of the row.<br />
<br />
The constructor requires a ColumnFormatter implementation for the DAO object you are creating. This is a little abstract, so hold off your questions until later.<br />
<br />
<b>ContactColumnFormatter</b><br />
let us dig deeper into a real implementation. So we have a table of Contacts which we are going to use the generic base class for therefore we need to create this class and implement the ColumnFormatter.<br />
<pre class="prettyprint">public class ContactColumnFormatter extends ColumnFormatter {
</pre><br />
<b>Create the annotation</b><br />
<pre class="prettyprint">@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.PARAMETER })
@BindingAnnotation
public @interface ContactTableAnnot {
}
</pre><br />
<b>Ginjector</b><br />
<pre class="prettyprint">SohoTable<contact> getSohoTableOfContact();
</contact></pre><br />
<b>Create the ContactTableProvider</b><br />
<pre class="prettyprint">public class ContactTableProvider implements Provider<SohoTable<Contact>>{
private final Provider<ContactColumnFormatter> providerFormatter;
@Inject
public ContactTableProvider(Provider<ContactColumnFormatter> providerFormatter) {
this.providerFormatter = providerFormatter;
}
@Override
public SohoTable<Contact> get() {
return new SohoTable<Contact>(providerFormatter.get());
}
}
</pre>Here we inject the correct ColumnFormatter for the Contact table.<br />
<br />
<b>Wire up the classes in the ClientModule (AbstractGinModule)</b><br />
<pre class="prettyprint">bind(ContactColumnFormatter.class);
bind(ContactTableProvider.class);
bind(new TypeLiteral<SohoTable<? extends HasReadId>>(){}).annotatedWith(ContactTableAnnot.class).toProvider(ContactTableProvider.class);
</pre>This is where we where the main action takes place. All the subclasses are wired up. The final line is the cool one. We need to use a TypeLiteral in order to wire up the generic elements. The annotated item shows how to wire up the annotation with the correct provider.<br />
<br />
<b>This is all very good but how do I use it?</b><br />
<pre class="prettyprint">@UiField(provided = true)
SohoTable<Contact> contactTable;
@Inject
public RolodexView(@ContactTableAnnot SohoTable<? extends HasReadId> contactTable) {
this.contactTable = (SohoTable<Contact>) contactTable;
</pre>Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com2tag:blogger.com,1999:blog-3895474834344383709.post-32227336535590115252011-01-10T19:46:00.000-08:002011-03-10T09:07:46.614-08:00A personal review of GWT for 2010<p>2010 has been an exciting year and I wanted to thank everyone who commented, got in touch and generally helped out. A big thankyou goes out to the people at <a href="http://code.google.com/p/gwt-platform/" target="_blank">GWTP project</a>. Philippe and Christian thanks for all your help in utilising the framework in my example application.</p><p>The year started with a change of career. For the past 15 years I have primarily been a Microsoft developer working for various commercial interests in London, Iceland, and now the USA. Currently living in Seattle, the Gaceland for computer programmers, or as we are now known Software Engineers, I decided that it was time to change my career track and learn a proper programming language (let the flame wars begin). </p><p>I am now sure whether I particularly dislike Windows, or whether I just needed a change of scenery but the Microsoft programming platform doesn't jive with my liberal view on life. I always wanted to learn an open source language, partly because I am an academic at heart and partly t stick it to the man. So the scene was set, and the only real option was to learn the current professional language de jour, JAVA.</p><p>One thing I also failed to mention was my love of Google. Any company which adopts open source as much as they have means they have to be admired in some way. Computer Programming tools are not proprietary systems. They are ideas that should be shared with everyone, in the same way that the cure for Malaria, will one day hopefully. I am not saying that all software built with open source tools should not be commercial far from it. But the ideas and tools we use should be at their core.</p><p>So I was learning Java and has a long term ASP.Net developer was looking for something that improved my programming environment. Google App Engine was the first oh wow moment three years ago, where I thought, this takes all the hassle out of programming. Then when I discovered Google Web Toolkit and what that actually means for feature rich internet applications. I thought oh wow oh wow.</p><p>So for the past year I have been learning Java with GWT on GAE. I learn best by example and building a contact application was the best way forward. I have a passion for helping small businesses and developing software which is functionally logical. So much software is plain old bad. GWT liberates the developer to programme professionally at all levels in the stack, thus improving and professionalising their daily routine. Google continues to build on this great architecture by partnering with Spring and Roo, to introduce Rapid Application Development tools. Plus they continue to enhance and develop the library. Speed Tracer looks awesome, performance tuning built in on the server and client side. Need I say more. Google needs to be congratulated for this piece of kit because it has improved my development daily routine no end.</p><p>Where am I now? Well on the basis of my skills developed during the past year I have landed a job with a startup, doing yes you guessed it... Java-GWT development. 2011 continues to be exciting. I also transferred to a Mac which I have been wanting to do for ages, and with the launch of this new career it will help me do so. Here is to 2011. </p><p>Continue to read, continue to ask questions, and lets have a great 2011.</p><p><a href="http://cheat.errtheblog.com/s/git/">Your link text here.</a></p>Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com3tag:blogger.com,1999:blog-3895474834344383709.post-12358134328281915152010-12-12T20:08:00.001-08:002011-05-13T15:15:05.488-07:00CellTable Examples<iframe align="left" frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=gwtsu-20&o=1&p=8&l=bpl&asins=0321705149&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr" style="align: left; height: 245px; padding-right: 10px; padding-top: 5px; width: 131px;"></iframe>Over the last few weeks I thought it was high time to experiment with the new Data Presentation widgets released in GWT version 2.1. It has been an interesting experience to say the least and as my life motto goes it is a journey not the destination. Anyhow I came across a particularly good collection of CellTable examples that I wanted to share. See this link for details:<br />
<a href="http://stackoverflow.com/questions/2891803/how-to-use-gwt-2-1-data-presentation-widgets">http://stackoverflow.com/questions/2891803/how-to-use-gwt-2-1-data-presentation-widgets</a>Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com1tag:blogger.com,1999:blog-3895474834344383709.post-60030860599660047552010-11-11T09:57:00.001-08:002010-11-11T09:57:04.321-08:00Conditional Logic and GUICE<p>For <a href="http://www.google.com/enterprise/marketplace/viewListing?productListingId=1940+4324839027261926410" target="_blank">Contact Personal Assistant</a> I am using GUICE. After being introduced to Dependency Injection, or Inversion of Control, I appreciate its awesomeness, if I don’t fully understand it. One of my main issues with fully adopting this paradigm shift, has been the usual barrage of questions a developer asks and answers in their own head in a daily basis, and the main one for me so far was.</p> <p><strong>How do I implement a conditional logic for an implementation instance based on runtime parameters?</strong></p> <p>Sounds a little abstract, I know. So lets try an example. Imagine you have a control which renders some information from a IDataServer interface but at runtime you have several Implementations of the IDataServer interface to chose from.</p> <p>I have thought of many ways this could be achieved, but have known, them all to be hacky, my implementation based on how I currently understand GUICE, and trying to fit it into what I require. As they say with great power comes great responsibility, and I want to use this framework correctly, not in hacked way that I can get it to work given my current level of knowledge.</p> <p>It turns out the solution is as simple as it is beautiful:</p> <p><strong>USE MAP BINDER!</strong></p> <p>Luckily the answer is discussed on this <a href="http://groups.google.com/group/google-guice/browse_thread/thread/3a452d6d7b1acf35/1c95de1d9366819b?lnk=gst&q=conditional#1c95de1d9366819b" target="_blank">thread</a> which I replicate here: <div class="csharpcode"><pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">public</span> <span class="kwrd">class</span> CalculatorModule extends AbstractModule { </pre><pre><span class="lnum"> 2: </span> <span class="kwrd">protected</span> <span class="kwrd">void</span> configure() { </pre><pre class="alt"><span class="lnum"> 3: </span> MapBinder<Types, Class<ICalculator>> mapbinder </pre><pre><span class="lnum"> 4: </span> = MapBinder.newMapBinder(binder(), Types.<span class="kwrd">class</span>, </pre><pre class="alt"><span class="lnum"> 5: </span>ICalculator.<span class="kwrd">class</span>); </pre><pre><span class="lnum"> 6: </span> mapbinder.addBinding(Types.A).toInstance(ACalculator.<span class="kwrd">class</span>); </pre><pre class="alt"><span class="lnum"> 7: </span> mapbinder.addBinding(Types.B).toInstance(BCalculator.<span class="kwrd">class</span>); </pre><pre><span class="lnum"> 8: </span> mapbinder.addBinding(Types.C).toInstance(CCalculator.<span class="kwrd">class</span>); </pre><pre class="alt"><span class="lnum"> 9: </span> } </pre><pre><span class="lnum"> 10: </span> } </pre><pre class="alt"><span class="lnum"> 11: </span>@Singleton </pre><pre><span class="lnum"> 12: </span><span class="kwrd">public</span> <span class="kwrd">class</span> CalculatorFactory { </pre><pre class="alt"><span class="lnum"> 13: </span> <span class="kwrd">private</span> final Injector injector; </pre><pre><span class="lnum"> 14: </span> <span class="kwrd">private</span> final Map<Types, Class<Calculator>> calculators; </pre><pre class="alt"><span class="lnum"> 15: </span> @Inject </pre><pre><span class="lnum"> 16: </span> <span class="kwrd">public</span> CalculatorFactory(Injector injector, Map<Types, </pre><pre class="alt"><span class="lnum"> 17: </span>Class<Calculator>> calculators) { </pre><pre><span class="lnum"> 18: </span> <span class="kwrd">this</span>.injector = injector; </pre><pre class="alt"><span class="lnum"> 19: </span> <span class="kwrd">this</span>.calculators = calculators; </pre><pre><span class="lnum"> 20: </span> } </pre><pre class="alt"><span class="lnum"> 21: </span> <span class="kwrd">public</span> ICalculator create(UserGroup group) { </pre><pre><span class="lnum"> 22: </span> injector.getInstance(calculators.get(group.getType)); </pre><pre class="alt"><span class="lnum"> 23: </span> } </pre><pre><span class="lnum"> 24: </span>} </pre></div><br /><style type="text/css">.csharpcode, .csharpcode pre<br />{<br /> font-size: small;<br /> color: black;<br /> font-family: consolas, "Courier New", courier, monospace;<br /> background-color: #ffffff;<br /> /*white-space: pre;*/<br />}<br />.csharpcode pre { margin: 0em; }<br />.csharpcode .rem { color: #008000; }<br />.csharpcode .kwrd { color: #0000ff; }<br />.csharpcode .str { color: #006080; }<br />.csharpcode .op { color: #0000c0; }<br />.csharpcode .preproc { color: #cc6633; }<br />.csharpcode .asp { background-color: #ffff00; }<br />.csharpcode .html { color: #800000; }<br />.csharpcode .attr { color: #ff0000; }<br />.csharpcode .alt <br />{<br /> background-color: #f4f4f4;<br /> width: 100%;<br /> margin: 0em;<br />}<br />.csharpcode .lnum { color: #606060; }<br /></style><br /></p><br /><br /><p>This example uses a calculator factory to allow the user to select whether they want implementation A, B or C. Simply inject the calculator factory into whichever class requires it.</p><br /><p>Beautiful!</p> Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com0tag:blogger.com,1999:blog-3895474834344383709.post-35939654292286164192010-11-03T16:40:00.001-07:002010-11-03T16:49:38.702-07:00Code Formatting Live Writer Plugins.<p>That’s It! I have had enough of my code snippets going awry when posting to the Blogger platform. I typically use Live Writer to blog so I am now going to review the code syntax formatters and declare a winner. Well my preferred formatter anyway. The Live Writer plugins are:</p> <ol> <li>Code Snippet</li> <li>Insert Code</li> <li>Source Code</li> <li>Source Code (another one)</li> <li>WintyCodeArea</li></ol> <p>Lets take a look at how they format the same bit of code.</p> <h2>Code Snippet</h2> <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"> <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1"> 1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> DynaTable implements EntryPoint {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2"> 2:</span> </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3"> 3:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> onModuleLoad() {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4"> 4:</span> <span style="color: #008000">// Find the slot for the calendar widget.</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5"> 5:</span> <span style="color: #008000">//</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6"> 6:</span> RootPanel slot = RootPanel.get(<span style="color: #006080">"calendar"</span>);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7"> 7:</span> <span style="color: #0000ff">if</span> (slot != <span style="color: #0000ff">null</span>) {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8"> 8:</span> SchoolCalendarWidget calendar = <span style="color: #0000ff">new</span> SchoolCalendarWidget(15);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9"> 9:</span> slot.add(calendar);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10"> 10:</span> </pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11"> 11:</span> <span style="color: #008000">// Find the slot for the days filter widget.</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12"> 12:</span> <span style="color: #008000">//</span></pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13"> 13:</span> slot = RootPanel.get(<span style="color: #006080">"days"</span>);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14"> 14:</span> <span style="color: #0000ff">if</span> (slot != <span style="color: #0000ff">null</span>) {</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum15"> 15:</span> DayFilterWidget filter = <span style="color: #0000ff">new</span> DayFilterWidget(calendar);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum16"> 16:</span> slot.add(filter);</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum17"> 17:</span> }</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum18"> 18:</span> }</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum19"> 19:</span> }</pre><!--CRLF--><pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum20"> 20:</span> }</pre><!--CRLF--></div></div><br /><h2>Insert Code</h2><br /><div class="csharpcode"><pre class="alt"><span class="lnum"> 1: </span><span class="kwrd">public</span> <span class="kwrd">class</span> DynaTable implements EntryPoint {</pre><pre><span class="lnum"> 2: </span> </pre><pre class="alt"><span class="lnum"> 3: </span> <span class="kwrd">public</span> <span class="kwrd">void</span> onModuleLoad() {</pre><pre><span class="lnum"> 4: </span> <span class="rem">// Find the slot for the calendar widget.</span></pre><pre class="alt"><span class="lnum"> 5: </span> <span class="rem">//</span></pre><pre><span class="lnum"> 6: </span> RootPanel slot = RootPanel.get(<span class="str">"calendar"</span>);</pre><pre class="alt"><span class="lnum"> 7: </span> <span class="kwrd">if</span> (slot != <span class="kwrd">null</span>) {</pre><pre><span class="lnum"> 8: </span> SchoolCalendarWidget calendar = <span class="kwrd">new</span> SchoolCalendarWidget(15);</pre><pre class="alt"><span class="lnum"> 9: </span> slot.add(calendar);</pre><pre><span class="lnum"> 10: </span> </pre><pre class="alt"><span class="lnum"> 11: </span> <span class="rem">// Find the slot for the days filter widget.</span></pre><pre><span class="lnum"> 12: </span> <span class="rem">//</span></pre><pre class="alt"><span class="lnum"> 13: </span> slot = RootPanel.get(<span class="str">"days"</span>);</pre><pre><span class="lnum"> 14: </span> <span class="kwrd">if</span> (slot != <span class="kwrd">null</span>) {</pre><pre class="alt"><span class="lnum"> 15: </span> DayFilterWidget filter = <span class="kwrd">new</span> DayFilterWidget(calendar);</pre><pre><span class="lnum"> 16: </span> slot.add(filter);</pre><pre class="alt"><span class="lnum"> 17: </span> }</pre><pre><span class="lnum"> 18: </span> }</pre><pre class="alt"><span class="lnum"> 19: </span> }</pre><pre><span class="lnum"> 20: </span>}</pre></div><br /><style type="text/css">.csharpcode, .csharpcode pre<br />{<br /> font-size: small;<br /> color: black;<br /> font-family: consolas, "Courier New", courier, monospace;<br /> background-color: #ffffff;<br /> /*white-space: pre;*/<br />}<br />.csharpcode pre { margin: 0em; }<br />.csharpcode .rem { color: #008000; }<br />.csharpcode .kwrd { color: #0000ff; }<br />.csharpcode .str { color: #006080; }<br />.csharpcode .op { color: #0000c0; }<br />.csharpcode .preproc { color: #cc6633; }<br />.csharpcode .asp { background-color: #ffff00; }<br />.csharpcode .html { color: #800000; }<br />.csharpcode .attr { color: #ff0000; }<br />.csharpcode .alt <br />{<br /> background-color: #f4f4f4;<br /> width: 100%;<br /> margin: 0em;<br />}<br />.csharpcode .lnum { color: #606060; }<br /></style><br /><br /><h2>Source Code (1)</h2><br /><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:5645ede1-ee85-4c60-98d5-08d2298af3af" class="wlWriterEditableSmartContent"><pre class="brush: java; gutter: true; first-line: 1; tab-size: 4; toolbar: true; width: 400px; height: 300px;" style=" width: 400px; height: 300px;overflow: auto;">public class DynaTable implements EntryPoint {<br /><br /> public void onModuleLoad() {<br /> // Find the slot for the calendar widget.<br /> //<br /> RootPanel slot = RootPanel.get("calendar");<br /> if (slot != null) {<br /> SchoolCalendarWidget calendar = new SchoolCalendarWidget(15);<br /> slot.add(calendar);<br /><br /> // Find the slot for the days filter widget.<br /> //<br /> slot = RootPanel.get("days");<br /> if (slot != null) {<br /> DayFilterWidget filter = new DayFilterWidget(calendar);<br /> slot.add(filter);<br /> }<br /> }<br /> }<br />}</pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div><br /><h2>Source Code (2)</h2><pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> DynaTable <span style="color: #0000ff">implements</span> EntryPoint {<br /></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> onModuleLoad() {<br /></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> <span style="color: #008000">// Find the slot for the calendar widget.</span><br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> <span style="color: #008000">//</span><br /></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> RootPanel slot = RootPanel.get("<span style="color: #8b0000">calendar</span>");<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> <span style="color: #0000ff">if</span> (slot != <span style="color: #0000ff">null</span>) {<br /></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> SchoolCalendarWidget calendar = <span style="color: #0000ff">new</span> SchoolCalendarWidget(15);<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> slot.add(calendar);<br /></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> <span style="color: #008000">// Find the slot for the days filter widget.</span><br /></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> <span style="color: #008000">//</span><br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> slot = RootPanel.get("<span style="color: #8b0000">days</span>");<br /></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> <span style="color: #0000ff">if</span> (slot != <span style="color: #0000ff">null</span>) {<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> DayFilterWidget filter = <span style="color: #0000ff">new</span> DayFilterWidget(calendar);<br /></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> slot.add(filter);<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> }<br /></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> }<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> }<br /></pre><pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">}<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"></pre></pre><br /><div class="mycode"></div><br /><br /><div class="mycode"></div><br /><div class="mycode"></div><br /><br /><h2>Winty Code Area</h2><br /><p>Didn’t work.</p><br /><h2>Conclusions</h2><br /><p>Based on the visuals above and interface in Windows Live Writer. My nomination goes to…. drum roll please… Code Snippet.</p> Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com1tag:blogger.com,1999:blog-3895474834344383709.post-83150399661726384362010-10-06T14:59:00.000-07:002010-10-06T14:59:19.477-07:00Contact Personal Assistant LaunchesWell I have some exciting news... Contact Personal Assistant (<a href="http://www.contactpa.com/">www.contactpa.com</a>) formerly known as sohocrm.appspot.com, has been accepted in the Google Apps Marketplace. Since we all like an image here it is. It can also be viewed <a href="https://www.google.com/enterprise/marketplace/viewListing?productListingId=1940+4324839027261926410">here</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgotne_cNPuq5qOvM501NxkVzkHHXFBSjw31Pbj_Q-GRzpOk58dyCijOdroG8Otc6IvCY9swEecOlLkj0M11mNqD8cY1ILvXJXeLkyLxXnjXbjOOj0g_JC-n0bc3tjbqjIfl7lIr0_Ioc4/s1600/C:%5Cfakepath%5CScreenshot-7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="182" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgotne_cNPuq5qOvM501NxkVzkHHXFBSjw31Pbj_Q-GRzpOk58dyCijOdroG8Otc6IvCY9swEecOlLkj0M11mNqD8cY1ILvXJXeLkyLxXnjXbjOOj0g_JC-n0bc3tjbqjIfl7lIr0_Ioc4/s400/C:%5Cfakepath%5CScreenshot-7.png" width="400" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: left;">This is a great milestone for the product, it has been a few months in development as I have learned a whole host of new technologies and frameworks. It has been tough, but interesting, and that's what I love about software engineering, its constant puzzle solving nature. Feel free to install Contact Personal Assistant to your Google Apps domain, or use it freely as a standalone product.</div>Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com1tag:blogger.com,1999:blog-3895474834344383709.post-59034432671637375532010-09-30T08:32:00.000-07:002010-09-30T08:32:08.029-07:00Creating a TabPanel in UIBinder Declarative Layout ViewSome posts just need to be short and sweet. Looking to create a TabPanel in UiBinder for GWT? Check out this <a href="http://giantflyingsaucer.com/blog/?p=1062">article</a> and code below:<br />
<br />
<g:TabLayoutPanel addStyleNames="{style.tabPanelExample1}"<br />
ui:field="tabPanel" barUnit="PX" barHeight="60" width="375px"<br />
height="150px"><br />
<g:tab><br />
<g:header><br />
UiBinder Tab 1<br />
</g:header><br />
<g:HTML><br />
Hello tab 1<br />
<br /><br />
Good bye!<br />
</g:HTML><br />
</g:tab><br />
<g:tab><br />
<g:header><br />
UiBinder Tab 2<br />
</g:header><br />
<g:HTML><br />
<h2>Hello tab 2</h2><br />
</g:HTML><br />
</g:tab><br />
<g:tab><br />
<g:header><br />
UiBinder Tab 3<br />
</g:header><br />
<g:HTML><br />
<strong><br />
<i><br />
<u>Hello tab number 3</u><br />
</i><br />
</strong><br />
</g:HTML><br />
</g:tab><br />
</g:TabLayoutPanel>Anonymoushttp://www.blogger.com/profile/17596228613938166964noreply@blogger.com0