Showing posts with label tutorial. Show all posts
Showing posts with label tutorial. Show all posts

Friday, May 13, 2011

XML to POJO Mapper for GWT using a GDATA Example with Google Contacts (ContactEntry).

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?

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?

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. 

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.

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?

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.

Step 1: Extract XML
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:
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();
}
Step 2: Transfer to Client
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.
Step 3: Create POJO
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: http://code.google.com/p/piriti/
Piriti (Maori for "bridge") is a JSON and XML mapper for GWT based on annotations and deferred binding. The following code snippets show the basic idea behind Piriti.   
So create a POJO and add these lines to the top of your POJO class:
public class ContactEntrySoho {

public static interface ContactEntrySohoReader extends XmlReader { }
public static final ContactEntrySohoReader XML = GWT.create(ContactEntrySohoReader.class);
These lines are used when mapping the POJO members to their XML nodes.
Step 4 : Map atom:title to an instance member
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:
<atom:title type='text'>Alan UserA1</atom:title>
Now lets look at how we would map this using XPath in the Pojo:
@Path("atom:title") private String title;
For a more in-depth view of XPath look online for various cheat-sheets and tutorials it is very powerful and very useful.
Step 5 : Load the Pojo
All we need to do now is load the POJO with information to do this see the below:
@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;
}
}
The namespaces tell the parser what the tag mean and correspond to the root note elements of the ContactEntry XML:
<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'>
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.
Step 6 : A more complex example please sir.
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.
The XML in ContactEntry:
<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>
The data in our parent ContactEntrySoho class:
@Path("//gd:structuredPostalAddress") private List<GDStructuredPostalAddress> gdStructuredPostalAddresses;
Wait what is GDStructuredPostalAddress? This is another POJO with the headers defined in Step 3.
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;
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 ;).
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.

Tuesday, August 17, 2010

Four easy steps to implementing a ClickHandler in a composite control.

After developing a composite control a click handler interface (ClickHandler) is required to respond to user events. A typically example might be the type of thing shown as a row in your Gmail email list. You have developed a control which nicely lays out all the relevant information in the row, but the row as a whole should fire a click event when clicked.

This kind of implementation is easy, but it can get confusing especially if you are new (like me) to this kind of expert level programming. So for my own benefit and yours this is how it is implemented.

Step 1 : Implement HasClickHandlers Interface
In the child composite control first implement the HasClickHandlers interface:

public class ApplicationMenuLink extends Composite implements HasClickHandlers {

Step 2 : Add the unimplemented methods

@Override
public HandlerRegistration addClickHandler(ClickHandler handler) {
  return addHandler(handler, ClickEvent.getType());
}

Step 3 : Fire the event when needed

@UiHandler("hyperlinkControlInComposite")
void doClick(ClickEvent e){
  this.fireEvent(e);
}

Step 4 : Implement handler in the parent control

instanceOfChildComposite.addClickHandler(new ClickHandler() {
  @Override
  public void onClick(ClickEvent event) {
    //Do Stuff
  }
}));

or using the UiHandler convention:

@UiHandler("instanceOfChildComposite")
void doClick(ClickEvent e){
  //Do Stuff
}

Conclusion
Et Voila! Thats all there is to it. As usual the path to this solution is a lot more tortuous than it would appear, but hopefully now I have it here it will be simpler for me and all us GWT developers.

Tuesday, June 1, 2010

Create a GWT Contact Application in 10 easy steps.

Google GWT and Spring Source have joined forces to make it easier to develop web applications by developing a tool which creates your data models, your web gui interface and all the web-server communication code in a few easy command line statements.  This was demo’d at Google IO 2010 and I aim to replicate the steps required here, including any pitfalls to help you jump start your GWT development.

SpringSource Tool Suite (STS) Is a flavor of Eclipse that includes all the necessary functionality to get this working.  At it’s core is a Roo Project where you create project and define entities using the Roo Shell.  This allows you to quickly get a Database, GWT Front End and connectivity code build without writing a single piece of code.

The source data and graphics for this article is from this web page.  I have outlined my steps taken when completing it and any pitfalls I came across.   http://www.thescreencast.com/2010/05/how-to-gwt-roo.html

The Steps REQUIRED

Step 1 : Setup your system

Download and setup Spring Source Tool Suite using the first screencast on this page:

http://www.thescreencast.com/2010/05/how-to-gwt-roo.html

Step 2 : New Roo Project

image

Enter Project Settings and Click Next

image  

Click Finish, and Yes to Turn Weaving Service On

image

No to Restart Now

image

Step 3 : Goto Roo Shell

Ensure project is selected in Project Hierarchy

image

Setup Persistence

image

Step 4 : Create Employee Entity

image 

Step 5 : Create Employee Entity Fields

Field firstName

image

Field lastName

image

Step 6 : Create GWT – Front End

image

Step 7 : Setup Google Web tool Kit Settings

image

image

Step 8 : Enable Maven Dependency

image

Step 9 : Run Project

image

image

image

Step 10 : Goto Browser

image 

Pitfalls to watch out for

Enable Maven Dependency:  This is one of the last stages of the demo and in the screen case it appears to work instantly.  This is not the case.  You will notice Eclipse in a busy mode for a few minutes as it configures itself.

Additional Info

Video from Google IO demonstrating this feature:

Thursday, March 11, 2010

How to update eclipse to the latest GWT and GAE SDKs

This website covers all the main points but I spent ages trying to find a solution to this and following this page would have saved me a lot of time.  Click this Google page for more info

Monday, March 8, 2010

Baby Steps – Converting The Hello World Project to a UIBinder Model

As I step out onto the icy lake of GWT abandoning all I know about .Net I make my first foray into the UIBinder model.  One of the attractions of the latest version of GWT 2.0 is the inclusion of the UIBinder model.  At present there aren’t too many examples using this new methodology so documentation is scarce.  In an effort to reduce the amount of factors that prevent me from learning this technology, i.e. reducing the amount of things that can go wrong in a project, without having the knowledge yet to quickly fix them.  Did I mention that I am also learning Java too?  I am attempting to convert the standard Hello World project to use the UI Binder model.

The standard project is pretty cool, when you create a GWT project a Hello World application comes pre created which places a text box on the screen and after pressing a button throws a dialog telling you what you just pressed.  It send’s the input to the server and shows the returned message.  It’s simple enough to allow most people to follow the code.  Since there aren’t many UIBinder examples I thought why not convert this application to a UI Binder so it looks exactly the same.  So here goes..

Step 1 : Create a nEW PROJECT

Create a new Google App Engine Project in Eclipse.  I have assumed that you know how to install Eclipse and all the required Google SDKs for GWT and Google App Engine.  So go ahead and create a project and debug it.  You should see an application that looks something like the picture below:

Pic1 

Step 2 : Create UI BindER PACAKGE

Start as you mean to go on by creating an easy to understand project.  Lets create a new package for our UIBinder controls.  Since my company is called Live For Now Studios lets call it: 

com.livefornowstudios.demos.helloworld.client.uibinder



STEP 3 : Create new UIBINDER CONTROL



From File –> New –> UIBinder select this item and see the image below for the elements added to it:



Pic2In the image the package is: com.livefornowstudios.demos.helloworld.client.uibinder



After clicking finish this should create two files in your new UIBinder package these files will be:




  • LandingPage.java  (The behind the scenes code)


  • LandingPage.ui.xml (The visual component)





step 4 : Create the VISUAL CODE



In the file LangingPage.ui.xml we are going to complete the visual components of the Hello World application.   Since I am new to this I am going to explain the elements I know, but it took a bit of fiddling to get this working.  Visually it doesn’t look as identical to the Hello World application as I would like but if faithfully replicates what is happening.  So it is a good starting point for me and hopefully for yourself.  See the main visual code sections below:



    <g:VerticalPanel >

<g:HTML>
<h1>Web Application Starter Project</h1>
<b>Please enter your name:</b>
</g:HTML>

<g:HorizontalPanel>
<g:TextBox ui:field="nameField"></g:TextBox>
<g:Button ui:field="sendButton" text="Send" />
</g:HorizontalPanel>

<g:DialogBox ui:field="dialogBox">
<g:HTMLPanel>
<b>Sending name to the server:</b>
<g:Label ui:field="textToServerLabel"></g:Label>
<br /><b>Server replies:</b>
<g:Label ui:field="serverResponseLabel"></g:Label>
<g:Button ui:field="closeButton" text="Close" />
</g:HTMLPanel>
</g:DialogBox>
</g:VerticalPanel>


Vertical Panel: This is the main wrapper for the control which ensures that the items placed in it appear in a consistent vertical arrangement. 



Header:  This is the first element wrapped in the <h:HTML> tags.  This allows us to enter real HTML to add a header to the control.



HorizontalPanel: This panel ensures that anything added to it flows horizontally across the screen.



TextBox,Button: The <g:TextBox> controls are GWT implementation of a Text Box they are in ASP.Net terms the equivalent of <ASP:TextBox>.  Here we have added a Text Box and a button to initiate the postback.



DialogBox: This is the dialog box that is displayed once the message is received from the server.



step 4 : Add the CODE BEHIND



Most of this code is replacing what the EntryPoint code was doing in the original HelloWorld.  However now it is nicely encapsulated in a UIBinder Object and could be used throughout your application.



Step 1: Declare UI Objects



Somewhere near the top declare the objects in the UI xml declaration:



    @UiField Button sendButton;
@UiField PopupPanel dialogBox;
@UiField TextBox nameField;
@UiField Label textToServerLabel;
@UiField Label serverResponseLabel;
@UiField Button closeButton;



Step 2: Create constructor



Set the default behaviour of the objects in the contructor:



    public LandingPageHeader(String firstName) {
initWidget(uiBinder.createAndBindUi(this));
sendButton.setText(firstName);
dialogBox.setVisible(false);
}


Step 3: Add event clicks



    @UiHandler("sendButton")
void sendButton_onClick(ClickEvent e) {
sendNameToServer();
}

@UiHandler("closeButton")
void closeButton_onClick(ClickEvent e) {
dialogBox.hide();
sendButton.setEnabled(true);
sendButton.setFocus(true);
}


Step 4 : Handle Server-Client Interaction



/**
* Send the name from the nameField to the server and wait for a response.
*/
private void sendNameToServer() {
sendButton.setEnabled(false);
String textToServer = nameField.getText();
textToServerLabel.setText(textToServer);
serverResponseLabel.setText("");
greetingService.greetServer(textToServer,
new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
dialogBox.setTitle("Remote Procedure Call - Failure");
serverResponseLabel.addStyleName("serverResponseLabelError");
serverResponseLabel.setText(SERVER_ERROR);
dialogBox.center();
closeButton.setFocus(true);
}

public void onSuccess(String result) {
dialogBox.setTitle("Remote Procedure Call");
serverResponseLabel.removeStyleName("serverResponseLabelError");
serverResponseLabel.setText(result);
dialogBox.center();
closeButton.setFocus(true);
}
});
}


Step 5 : Change EntryPoint Code



Step 1 : Declare new control



private LandingPageHeader landingPageHeader = new LandingPageHeader("Hello"); 


Step 2: Change OnModuleLoad Control



    public void onModuleLoad() {

// Use RootPanel.get() to get the entire body element
// Add the new UIBinder version of this control to the web page.
RootPanel.get().add(landingPageHeader);

}


Final Thoughts



These changes highlight what needs to be done to change the UIBinder.  If you have any questions please drop me a line.



The full code can be downloaded here project title “HelloWorld” - http://code.google.com/p/gwt-20-demos/