Wednesday, November 28, 2012

RequireJs, JQuery, Less, Handlebars, Bootstrap and Jasmine

Attention: This is old stuff. New build instructions here

In the last post we started implementing our photodb backend code. Today we will give some love to our client side. The objective of this first version of the GUI is to provide the code base for new features. We will use RequireJs, JQuery, LessCss, HandlebarsTwitter Bootstrap and Jasmine.

photodb is a single-page application, therefore we won't use any server-side template tool like JSP, JSF or Apache Tapestry. We will use a simple standard "index.html" page and everything else will be loaded from it. The communication between the browser and the application will be entirely via XMLHttpRequest, and the server will send only JSON strings through the wire. Twitter Bootstrap will be the base of our GUI; Handlebars will take care of the templating; LessCss will compile our CSS file; JQuery will manipulate the DOM and trigger the ajax requests; RequireJs will load all the file dependencies for us; Jasmine will test everything.

Let's run this code! Execute the following commands to start the server.

mkdir -p ~/dev/demo2
cd ~/dev/demo2
wget http://people.apache.org/~tveronezi/photodb-day-2.tar.gz
tar -zxvf photodb-day-2.tar.gz
cd photodb
make start-tomee

Once you have your server running, go to http://localhost:8080/photodb-web/. You should see something like this.



Looks dummy, but there is a lot going on behind the scenes. Check what this page is loading.


Now check the "index.html" source code.



You may be asking where did all those requests come from? It is RequireJs doing its job by loading the dependencies for us. We don't need to touch the "index.html" file every time we add a new dependency. We simply need to change the "start.js" file for new "lib" dependencies or follow the module definition used by the RequireJs library. Looking for examples? Check the "start.js" or one of the files under the "photodb/photodb-web/src/main/webapp/app/js" directory. You may also go to their API to learn more about this great framework.

As you have noticed, when the page is loaded it shows a "Welcome to photodb!" message (My version of "Hello world!" :O) ). It is a floating div with an absolute position. The CSS rule of it is managed by LessCss, which generates CSS rules from our "app.less" file. If you want to add a new rule, update this file. Check what LessCss generates from "app.less"...




Handlebars uses the ".handlebars" files to create the templates. If you want to add a new template, create a file with ".handlebars" extension under the "photodb/photodb-web/src/main/webapp/app/js/templates" directory. To load this template, you should call the "get" function of the "ApplicationTemplates" module. Check this code:


In the exemple above, we would have two files: "my-template.handlebars" and "my-template-with-params.handlebars". The second one has a "myParam" value. In your template code it would be something like "<div>{{myParam}}<div>". You need to enumerate the template files the "ApplicationTemplates" module use. All the templates should be in the "files" variable defined in "photodb/photodb-web/src/main/webapp/app/js/ApplicationTemplates.js". Don't forget to check http://handlebarsjs.com/ for more information about templates.

Handlebars and LessCss create the "Welcome to photodb!", but JQuery is the one who adds it to the DOM. To see how JQuery does that, check the "photodb/photodb-web/src/main/webapp/app/js/view/GrowlNotification.js" file.


At the line 38 we get the template; At the line 43 we add it to the DOM; At the line 44 we perform a fancy "fadeIn" transition.

Now we need to test what we have. Jasmine to the rescue! Run the following commands to start Jasmine.

cd ~/dev/demo2/photodb
make run-jasmine

Now open your browser at http://localhost:8234. You should see the unit tests results.


In order to add a new test case, you should create a js file under the "photodb/photodb-web/src/test/javascript/test" directory. Check the "photodb/photodb-web/src/test/javascript/test/I18N.js" file.


It is a RequireJs module. You need to define the dependencies of your test. In this case, our test file depends on the "util/I18N" module implemented by the "photodb/photodb-web/src/main/webapp/app/js/util/I18N.js" file. If you want to test a brand new module, you may need to change the "photodb/photodb-web/src/test/resources/start.js" bootstrap file. Specifically, you may need to change the "require.config" call and the "REQUIREMENTS" object.


This is a javascript application, so there is no need to restart the server to test our code. When you change something under the "photodb/photodb-web/src/main/webapp/app" directory, just run "make up-static" to update the server.

tveronezi@botobox:~/dev/demo2/photodb$ make up-static

If you are just running unit tests, you don't need to run "make". Just refresh the http://localhost:8234 page and you are good to go.

Thats it! Now we have the skeleton of both back-end and front-end codes. We still have a lot to do, but we can be more productive by using these awesome tools.

Tuesday, November 27, 2012

Source-code of a JEE project with Java, Groovy and TomEE

Attention: This is old stuff. New build instructions here

Lets create our own enterprise application. Together we are going to learn how to implement a JEE application from scratch. We can also use this project as reference for real-world projects we may have. First we define the name of our application. Lets call it photodb.

What is photodb? It is an on-line photo sharing application. The user can upload photos, add comments and tag them. The user can configure the access control for all the tags, making tagged photos public, private (the default) or give access for some of his/her friends. So, what is the difference between picasaweb and this application? Well, I am sure picasaweb is great and has a lot more features then photodb, but you cannot install it in your own machine. Also, you didn't have the pleasure of implementing it!

The project will be implemented with java and groovy. Groovy is a dynamic-typed language that is less verbose than java. It makes very easy to create JavaBeans and it is handy when we need to create JUnit classes with mocked objects. Java is a strong-typed language and is usually more efficient than groovy. The good news is that with Gmaven we can use the best of both worlds in the same project. We will also use javascript in order to create a single-page application, but this is subject of another post.

Make sure you have Java JDK, Maven and Subversion installed in your computer. The source-code of the project is available here. If you use an unix-like OS, you can have the server running by executing a feel simple commands. Windows users may need to extract photodb-day-1.tar.gz (See 7zip) and check the the Makefile content. This file details all you need to do to build the system.

 mkdir -p ~/dev/demo  
 cd ~/dev/demo  
 wget http://people.apache.org/~tveronezi/photodb-day-1.tar.gz  
 tar -zxvf photodb-day-1.tar.gz  
 cd photodb  
 make start-tomee  

The second execution of "make start-tomee" will take a matter of seconds to complete (8 seconds in my computer), but the first execution of it may take some time. It does a check-out and builds the trunk version of the Apache TomEE server; It builds the photodb project; It downloads the last stable version of the server; And then it starts the stable server with our photodb project. If something does not work, you may need to check if all the builds were successful. You can find more information about TomEE/OpenEJB builds here.

You can call "make kill-tomee" to kill the server. "make start-tomee" kills the TomEE server before starting it again. "make clean" kills any running instance of Tomee, removes the server binaries and cleans the photodb directory. Calling "make start-tomee" after "make clean" is the same as calling "make start-tomee" for the first time.

The web layer has two access points: index.html (http://localhost:8080/photodb-web) and the CommandServlet (http://localhost:8080/photodb-web/cmd) .The index page is still empty, but the CommandServlet can be used to execute three commands:

http://localhost:8080/photodb-web/cmd?strParam={cmdName:'CreatePhoto', path: 'myPhoto'}

http://localhost:8080/photodb-web/cmd?strParam={cmdName:'AddComment',comment:'my Comment',photoUid=2}

http://localhost:8080/photodb-web/cmd?strParam={cmdName:'GetPhotoComments',photoUid=2}

A new action does not require a new servlet. If we want to call another service, we can create a new class under the "photodb.web.command.impl" package. This class should implement "photodb.web.command.Command" and should have a constructor with no parameter. This way we avoid creating extra servlets and avoid having dependency on any proprietary class of the photodb-service sub-project (See wiki).

The servivice layer has only one access point. The only public API is the ServiceFacade. This interface will have all the methods available to the outside world (See wiki).

Backlog:

  • Photo tags
  • User login
  • User access
  • Web page
  • Upload file Servlet
  • "And something else... I am sure. :O)"