Subscribe News Feed Subscribe Comments

Grails - How to execute the parameters data binding process in an integration test

When executing a request in a web application in Grails there is a process that allows to bind the request parameters with the controller params object. Grails have different listeners that are notified in order to do this binding.

The class UrlMappingsFilter, which is a Servlet filter that uses the Grails UrlMappings to match and forward requests to a relevant controller and action, is the one in charge of notifying these listeners that they need to execute to do the data binding. However, this step is not executed in an integration test, so if you need to test a controller action, you need to notify these listeners manually and the way to do it, is:

controller.request.getAttribute("org.codehaus.groovy.grails.WEB_REQUEST").informParameterCreationListeners()

So for example if you were using a JSON content type the listener JSONParsingParameterCreationListener would be notified and then it would do the request parameters parsing allowing you to use the controller.params object on your test.

It is important to execute this code before actually calling the controller action method that you want to test.

How to play a sound in a Firefox extension

What if you are working on a Firefox extension that needs to play a sound when an event occurs? Do you know what libraries to use or what you should do to accomplish this simple task? I am going to answer these questions for you!

Let's assume that the sound that we are going to play is in our content folder inside the extension, how do we retrieve the file path dynamically, i.e, depending on where the extension was installed?

First of all you have to know that Mozilla has a service called nsIExtensionManager that provides you with functions to execute tasks related to the extension like for example getting the path to the extension installation folder, so how do we use it?

We need to first instantiate the extension manager interface this way:

var em = Components.classes["@mozilla.org/extensions/manager;1"].getService(Components.interfaces.nsIExtensionManager);

Then to get the installation folder of our extension we do this:

var installationLocation = em.getInstallLocation(EXTENSION_ID);

As you can see in this code we are using a constant called EXTENSION_ID, you need to set this constant in your code with the ID of your extension. The ID of your extension is the ID you defined in your install.rdf file.

OK, we now have the installation location of our extension, so we now have to get the full location of the sound file we want to use and for that we are going to use the getItemFile function.

installationLocation.getItemFile(EXTENSION_ID, "chrome/chromeFiles/content/sound.wav");

As you can see here, we are looking for the file based on the extension installation location and we are indicating where in the extension to look. We said before we have our file in the content folder of the extension, so we pass that path as a parameter.

Until now what we have is the file location inside the extension, but we still need to create a file object to play the sound, right? Well, to create a file we use the Mozilla interface nsILocalFile and we instantiate and set the path contained in the fileLocation object like this:

var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);

file.initWithPath(fileLocation.path);


We can double check and make sure that the file really exists:

if (!file.exists()) {
// If the file doesn't exists, then return null
return null;
}

Now, if the file exists we can then play it, but how? Mozilla provides with an interface to play sounds, it is called nsISound and we instantiate it like this:

var player = Components.classes["@mozilla.org/sound;1"].createInstance(Components.interfaces.nsISound);

When playing a sound, the player needs to receive the location of the file as a nsIURI object, so we still need to convert our file into a nsIURI object and we do this by using the nsIIOService interface.

var ios = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);
var sound = ios.newFileURI(file);

Now we just need to play it!

player.play(sound);


...and that is it! Very simple!!

How to create a Windows Vista Gadget

We have discussed in previous posts how to create a very simple Google Gadget and how to add preferences to it, but in this post we are going to discuss how to create Windows Vista Gadget that you can place on your Windows Vista Sidebar or desktop.

Vista Gadgets are created using XML, HTML, CSS and Javascript, so if you are familiar with all these technologies, you won't have any problem.

OK, now I am going to guide you through the steps of creating a very simple Windows Vista Gadget that displays the current time based on your computer's clock.

So let's first start by creating a new folder with the name of your gadget, in our case let's call the gadget MyClock. Under our root gadget folder, create two folders one named css and the other one named js.

Vista Gadgets use a XML file as a descriptor for the gadget, so let's create a new file under the gadget root folder called myclock.xml with the following content:

<?xml version="1.0" encoding="utf-8" ?>
<gadget>
<name>My Clock</name>
<namespace>com.mycompany.myclock</namespace>
<version>1.0.0</version>
<author>
<info url="www.mycompany.com" />
<logo src="logo.png" />
</author>
<copyright>MyCompany © 2009</copyright>
<description>Windows Vista Gadget to check the current time.</description>
<icons>
<icon width="80" height="80" src="icon.png" />
</icons>
<hosts>
<host name="sidebar">
<base type="HTML" apiVersion="1.0.0" src="myclock.html" />
<permissions>full</permissions>
<platform minPlatformVersion="0.3" />
</host>
</hosts>
</gadget>

In the gadget manifest above we are saying that our gadget is named My Clock, we are also providing information about the author and most importantly we are saying that this gadget is going to reside on the sidebar and that the base point is the file named myclock.html.

As you can see, in the manifest we are referring to two images: logo.png and icon.png. The file logo.png is used when displaying the author information inside the Vista Gadgets directory, it is generally your company's logo, and icon.png is used on the Vista Gadgets gallery to describe the gadget, it is basically the gadget's icon. For these just create a couple of PNG files and place them on the gadget root folder.

For more information about the gadgets manifest check http://msdn.microsoft.com/en-us/library/aa965879(VS.85).aspx

Our next step is to create a Javascript file where we are going to place all the necessary Javascript code to create and to display the clock. Just create a new file under the js directory and name it myclock.js and add the following code to it:

var clockContainer = "";

function gadgetSetup(clockId) {
clockContainer = document.getElementById(clockId);
setClock();
}

function setClock(){
var mytime = new Date();
var hours = mytime.getHours();
var minutes = mytime.getMinutes();
var seconds = mytime.getSeconds();

var label = "AM";
if (hours > 12){
label = "PM";
hours = hours-12;
}
if (hours == 0) {
hours = 12;
}
if (minutes <= 9) {
minutes = "0" + minutes;
}
if (seconds <= 9) {
seconds = "0" + seconds;
}
clockContainer.innerHTML = hours + ":" + minutes + ":" + seconds + " " + label;

setTimeout("setClock()", 1000);
}

Now that we have the necessary Javascript code, let's create a new file under the root folder named myclock.html, this file is the main HTML file that acts as base point for the gadget.

Now that you have the HTML file created, add the following code:

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link href="css/myclock.css" rel="stylesheet" type="text/css" />
<script type='text/javascript' src='js/myclock.js' charset="utf-8"></script>
</head>

<body onLoad="gadgetSetup('myclock');">
<div id="myclock" class="clock">

</div>
</body>

</html>

In the HTML file what we have a DIV tag that is going to hold the clock, also we are saying that when the page is being loaded, call the gadgetSetup function that we previously defined in myclock.js.

Now we have the HTML and the Javascript code to display the clock, but we haven't done much to make it look nice, so let's create a new file under the css directory and name it myclock.css. Add the following code to this file:

body {
margin: 0px;
width: 120px;
height: 50px;
border: 2px solid #000;
}

#myclock {
width: 120px;
height: 50px;
background: red;
color: FFF;
text-align: center;
padding: 20px;
}

We are giving the gadget a size of 120px by 50px and we want to make it red and the text is going to be displayed in white.

Ok, we now have the main contents of our vista gadget clock, so how we install it? Very simple, take all the contents of the gadget root folder and compress it into a zip file named MyClock.zip, change the compressed file extension from .zip to .gadget and double click on the file. Windows Vista will recognize the .gadget file as a Vista Gadget installer and it would ask you if you really want to install this gadget, so click yes.

You should now see your new gadget on your sidebar. If you want you can drag it out the sidebar and put it into your desktop.

Hope this helps!!

How to add user preferences to your Google Gadget

In the previous post, we saw how to create a simple Google Gadget that reads the CNN.com Top Stories feeds and display them. We make it by default to display only 10 stories and to display the summaries, but what about if I want to see some more stories or less? or if I don't want to the see the summary, only the story headline? Well, there is a way for the user to customize the gadget , we just need to use User Preferences.

With user preferences we can set information in the gadget that is specific to the user. To have user preferences you just need to specify them inside the Module tag of the gadget. See the following example:

<UserPref name="show_summ" display_name="Show Summaries?" datatype="bool" default_value="false" required="true"/>

As you can see what you need to specify is the name of the preference, the display name, the data type, the default value and if it is required or not. The data type, the default value and required attributes are optional. The default value for data type is string and the default value for required is false.

Let's see how our CNN.com Top Stories gadget would look with preferences that will allow the user to set how many stories wants to see and if he/she wants to see the summary or not.
<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs
title="CNN.com Top Stories"
title_url="http://www.cnn.com/"
author="Your name"
author_email="youremail@domain.com"
description="Gadget to see the current CNN.com top stories."
width="450"
height="350"
scrolling="true">
<Require feature="dynamic-height"/>
</ModulePrefs>
<UserPref name="num_entries" display_name="Number of Entries:" default_value="5"/>
<UserPref name="show_summ" display_name="Show Summaries?" datatype="bool" default_value="false"/>


<Content type="html">
<![CDATA[
<style>
div#main_container {
font-size:12px;
font-family:Arial;
margin: 5px;
text-align: left;
text-decoration: none;
}

div#main_container h2 {
background: url(http://i2.cdn.turner.com/cnn/.element/img/1.0/logo/cnn.logo.rss.gif) no-repeat left top;
display: block;
height: 33px;
text-indent: -100000;
width: 144px;
}

</style>
<script type="text/javascript">

// Get userprefs
var prefs = new _IG_Prefs();
var summary = prefs.getBool("show_summ");
var entries = prefs.getInt("num_entries");


// Function to dipslay content retrieved from XML feed
function displayContent() {

// If user wants to display more than 50 entries, display an error
// and set the value to 50, the max allowed.
if (entries > 50)
{
alert("You cannot display more than 50 entries.");
entries = 50;
}


var url = "http://rss.cnn.com/rss/edition.rss";

// Use the _IG_FetchFeedAsJSON() function to retrieve core feed data from
// the specified URL. Then combine the data with HTML markup for display in
// the gadget.
_IG_FetchFeedAsJSON(url, processFeed, entries, summary);

}

// Function to process the feed
function processFeed(feed) {
var contentDiv = _gel("main_container");

if (feed == null) {
contentDiv.innerHTML = "Invalid data.";
return;
}

// Start building HTML string that will be displayed in gadget.
var html = "";

// Access the fields in the feed
html += "<h2>" + feed.Title + "</h2>";
html += "<div>" + feed.Description + "</div><br>";

// Access the data for a given entry
if (feed.Entry) {
for (var i = 0; i < feed.Entry.length; i++) {
html += "<div>" + "<a target='_blank' href='" + feed.Entry[i].Link + "'>" + feed.Entry[i].Title + "</a> ";
// The feed entry Date field contains the timestamp in seconds
// since Jan. 1, 1970. To convert it to the milliseconds needed
// to initialize the JavaScript Date object with the correct date,
// multiply by 1000.
var milliseconds = (feed.Entry[i].Date) * 1000;
var date = new Date(milliseconds);
html += date.toLocaleDateString();
html += " ";
html += date.toLocaleTimeString();
if (summary == true) {
html += "<br><i>" + feed.Entry[i].Summary + "</i>";
}

html += "</div>";
}
}

contentDiv.innerHTML = html;

// Adjust gadget height according to contents
_IG_AdjustIFrameHeight();

}

_IG_RegisterOnloadHandler(displayContent);


</script>

<div id="main_container"></div>

]]>
</Content>
</Module>

As you saw in the code we need the following code to retrieve the user preferences:

var prefs = new _IG_Prefs();
var summary = prefs.getBool("show_summ");
var entries = prefs.getInt("num_entries");


There is a "get" method for each data type available. To get more information about user preferences click here.

Allowing the user to set up its preferences is really simple and it adds a lot value to the gadget functionality!

How to create a Google Gadget

Google Gadgets are a great tool, they allow you to have specific information in, what you could call, a small HTML page. You can export your gadgets to iGoogle, Google Desktop, Google Toolbar, to any web page and even you can create a Windows Vista Gadget based on them, isn't that great?

In this post, I am going to walk you through the creation of a simple gadget, but first let's talk about what Google Gadgets are.

Google gadgets are small pieces of code created using XML, HTML, CSS and Javascript that allow you to display data. These gadgets can be embedded in certain applications allowing you to export your information more easily.

They are really easy to create, you just need basic knowledge of HTML and JavaScript and Google provides you with JavaScript APIs to you make your life easier, you can check them in their Legacy Gadgets API Developer's Guide

One of the greatest advantages about a gadget is that they can be used in so many places, but you manage only one source code, so if you need to apply a change to your gadget, you just do it and then all the places were the gadget is used would be updated with no new installation or update required.

Before we start coding, let's talk about a little bit about the gadget components. A Google Gadget is a XML file that contains one big tag called Module that encloses the gadget, then we have two main different components, the module preferences and the gadget content.

The module preferences are tags that you use to set the gadget information like title, author, width, height, etc. In our example, you will see this tag <Require feature="dynamic-height"/>, this tells the gadget parser that the height should be dynamically changed depending on the size of the content. This feature only works with iGoogle though.

The gadget content is where you do all the work, here you need to specify a type, mainly "html" if you want to have your HTML and JavaScript in your gadget or "url" if you want the gadget content to live on a remote web page referenced by a URL in the gadget spec. Inside this tag you can code JavaScript and HTML to layout your data, and CSS if you want to give some style to your content. You need to enclose your code into the tags ![CDATA[ and ]].

For this post, we are going to create a simple gadget that reads the CNN.com top stories feed and display them using the API called _IG_FetchFeedAsJSON to read the feed as JSON. You will see that this code is really simple and easy to follow.

To work with Google gadgets you need a proper editor, you could use notepad if you want at first, but then you would need a way to publish it. Google already provides a tool called Google Gadget Editor (GGE) which is a gadget itself, so you can embedded it in your iGoogle, which allows you to edit your gadget and preview it in the same editor if want to. You can add it to your iGoogle by clicking here.

Now that you have the GGE in your iGoogle page, copy the following code into your GGE.

<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs
title="CNN.com Top Stories"
title_url="http://www.cnn.com/"
author="Your name"
author_email="youremail@domain.com"
description="Gadget to see the current CNN.com top stories."
width="450"
height="350"
scrolling="true">
<Require feature="dynamic-height"/>
</ModulePrefs>

<Content type="html">
<![CDATA[
<style>
div#main_container {
font-size:12px;
font-family:Arial;
margin: 5px;
text-align: left;
text-decoration: none;
}

div#main_container h2 {
background: url(http://i2.cdn.turner.com/cnn/.element/img/1.0/logo/cnn.logo.rss.gif) no-repeat left top;
display: block;
height: 33px;
text-indent: -100000;
width: 144px;
}
</style>

<script type="text/javascript">

// Function to dipslay content retrieved from XML feed
function displayContent() {

var url = "http://rss.cnn.com/rss/edition.rss";
// Use the _IG_FetchFeedAsJSON() function to retrieve core feed data from
// the specified URL. Then combine the data with HTML markup for display in
// the gadget.
// Let's say we want to display only 10 entries and that we want to display the summary
var entries = 10;
var summary = true;
_IG_FetchFeedAsJSON(url, processFeed, entries, summary);
}

// Function to process the feed
function processFeed(feed) {
var contentDiv = _gel("main_container");

if (feed == null) {
contentDiv.innerHTML = "Invalid data.";
return;
}

// Start building HTML string that will be displayed in gadget.
var html = "";

// Access the fields in the feed
html += "<h2>" + feed.Title + "</h2>";
html += "<div>" + feed.Description + "</div><br>";

// Access the data for a given entry
if (feed.Entry) {
for (var i = 0; i < feed.Entry.length; i++) {
html += "<div>" + "<a target='_blank' href='" + feed.Entry[i].Link + "'>" + feed.Entry[i].Title + "</a> ";
// The feed entry Date field contains the timestamp in seconds
// since Jan. 1, 1970. To convert it to the milliseconds needed
// to initialize the JavaScript Date object with the correct date,
// multiply by 1000.
var milliseconds = (feed.Entry[i].Date) * 1000;
var date = new Date(milliseconds);
html += date.toLocaleDateString();
html += " ";
html += date.toLocaleTimeString();
html += "<br><i>" + feed.Entry[i].Summary + "</i>";
html += "</div>";
}
}
// Set the html into the main container
contentDiv.innerHTML = html;

// Adjust gadget height according to contents
_IG_AdjustIFrameHeight();
}
// Register the function displayContent in the onLoad handler so it is called when the gadget is first loaded
_IG_RegisterOnloadHandler(displayContent);

</script>

<div id="main_container"></div>

]]>
</Content>
</Module>

As you can see in the code, the function _IG_FetchFeedAsJSON receives as parameters the feed URL and the name of the callback function in charge of processing and displaying the data.

In the callback function what we do first is to check if the JSON response we received is valid, if it isn't then we just display a message saying that the data is invalid. If the response is valid then we go through the JSON properties to retrieve the data and display it using HTML and CSS.

As you can see this particular API is really easy to use and understand, you just need some basic knowledge of Javascript and that is it!

Now that you have the code in your GGE, you can publish it to your iGoogle so you can see how the dynamic height works depending on the content. Also you can publish it to a web page. Just click on the File menu and select the Publish option. You will get a warning saying that we did not set the Thumbnail preference, but that is not going to affect the code itself, since the Thumbnail is used just to display the gadget Thumbnail in the Google Gadget Directory, so people know how the gadget looks like.

I hope this helps! Post your comments and/or questions!
 
Software Engineering | Costa Rica JUG
All contents copyright © 2007-2009, Maricel Quesada. All rights reserved.