Configuring a Ralink-chipset-based wireless USB card

July 27th, 2010 dpino No comments

I’m not very keen on hardware to be honest. Recently as my netstorage harddrive accidentally broke down, I decided to replace it for a brand-new minibarebone. I ended up buying lots of stuff, even a new monitor :P Together with the whole pack I also acquired an USB wireless device. It was an Edimax card, most likely a piece of hardware from just another Taiwanese vendor…

Initially I couldn’t get it working. It was a great surprise for me finding out there were drivers for Linux available at Edimax website. The drivers are published under the GPL license. Actually the only way to install the wireless card driver on Linux was by downloading the source code and compile it. Unfortunately it seems the vendor does not catch up with the pace of kernel development and the drivers were kind of outdated, in other words, didn’t compile successfully (you may want to check the UPDATE section at the end of this post before continuing).

The card was an Edimax 7711, featuring a Ralink rt3070sta chipset, a chipset widely available in other card models (actually according to Wikipedia Ralink claims to hold 12% of the World Wide WLAN chipset market). The rt2870sta module, available since 2.4 linux kernels, is also compatible with rt3070sta. Doing a lsmod, I could easily check what driver was being loaded.

After googling a bit I found out the problem why the card was not working was that rt2870sta driver has conflicts with the rt28000usb module (also being loaded at the same time). The solution was to blacklist rt2800usb preventing it to be loaded at boot time.

First, do a lsmod so you can check both rt2800usb and rt2870sta drivers are loaded.

lsmod | grep ^RT28
rt2870sta
rt2800usb

Before that is also convenient to check your USB wireless card is being detected. My card is a 7711 model, so I grep by 7711.

lsusb -v | grep -A 10 7711

The command above should return something. You can simlpy do a lsusb -v, and flick through the results searching for WLAN string, for instance.

The 7711 uses the rt2870sta driver. There are other models of cards using this module too.Type modinfo rt2870sta to get a list of all hardware models compatible with this driver. For instance, grepping by 7711 in my case, should return something.

modinfo rt2870sta | grep 7711

returns,

alias:          usb:v7392p7711d*dc*dsc*dp*ic*isc*ip*

At this point we’re certain of two things:

  • USB card is connected.
  • Card model, Edimax 7711 in my case, is supported by the rt2870sta driver.

We also know that both rt2870sta and rt2800usb drivers are being loaded, but they are not capable of working together, so it’s necessary to disable rt2800usb.

Edit /etc/modprobe.d/blacklist.conf and add:

# Wireless usb card
blacklist rt2800usb

As with many hardware configuration and settings I’m certain I won’t come up with this very same problem again in the future, eventually all the stuff related with this misconfiguration problem will be sorted out in a new distro or kernel release, but just hope this knowledge can be useful for others. As for me, I have learned a couple of Linux commands I was not aware of. The intuitive lsusb (list usb), modinfo and the blacklist concept (this has to be new as I don’t recall using it when enabling sound in Linux was a real challenge :) ).

UPDATE: Actually the drivers at Edimax website are outdated. Ralink has an updated version of the 3070 chipset drivers compatible with Linux kernels above 2.6.29v [Linux drivers avalable at Ralink website].

Categories: linux Tags:

ZK: Render a computed field in a row without using a Renderer

April 14th, 2010 dpino No comments

One of the things I really like about ZK is its capability for designing complex UI using just ZUL. But sometimes it’s not possible to lean just on ZUL code. Somehow you’re force to code a Renderer to circumvent certain drawbacks of the ZK framework.

One of this cases, which tends to happen rather to say often, is to render a Listbox or a Grid feeded by live-data while establishing at the same time some properties of the items being rendered. For instance, imagine you need to render a list of customers. For each customer there’s an extra column containing a button for editing customer’s personal data in an independent dialog window. Only users with granted permissions can edit customer’s personal data. It’s not a very ellaborate example but illustrates quite well a case where most likely you may need a Renderer.

<grid id=”gridCustomers”
        fixedLayout=”true”
        model=”@{customersController.customers}”>
    <columns>
        <column label=”Code” />
        <column label=”Name” />
        <column label=”Surname’” />
        <column label=”" />
    </columns>
    <rows>
        <row self=”@{each=’customer’}” value=”@{customer}” >
            <label id=”code” value=”@{customer.code}” />
            <label value=”@{customer.name}” />
            <label value=”@{customer.surname}” />
            <button sclass=”icon”
                image=”/common/img/ico_edit1.png”
                hoverImage=”/common/img/ico_edit.png”
                tooltiptext=”Edit”
                onClick=”customersController.edit(self.parent.value)” />
        </row>
    </rows>
</grid>

Why? The difficult part here is to set the attribute disabled for element edit button. There’s no way in ZUL for calling a method plus assigning its returned value to an attribute of a ZUL component. For instance,

<button disabled=”customersController.hasPermissions(self.parent.value)” />

The code above doesn’t work as disabled is defined as an attribute. Although attributes can be bound to an element (via a pair of get/set methods) using bindings, they cannot trigger methods in the controller in the same way events do.

However it’s possible to bind events and business-logic methods together.

<button onclick=”customersController.edit(self.parent.value)” />

The code above works as onclick is defined as an event. Events can trigger methods, whenever an event happens its associated method is executed.

Refactoring ZUL code into a Renderer is time-consuming and provides a much less elegant solution than doing it directly using ZUL. Struggling my head a bit about this problem, I managed to find a solution which with some little Java code, doesn’t require to refactor all the ZUL code into a Renderer.

The trick here is to code in ZUL as many things as you can. For those properties you cannot code in ZUL, simply overload the event onInitRender() of the element you need to tune and modify it directly from  Java code. Here’s an example:

public class CustomersController extends GenericForwardComposer {
 
   private Grid gridCustomers;
 
   public void doAfterCompose(Component comp) throws Exception {
      super.doAfterCompose(comp);
      gridCustomers.addEventListener("onInitRender", new EventListener() {
         @Override
         public void onEvent(Event event) throws Exception {
            gridCustomers.renderAll();
            final Rows rows = gridCustomers.getRows();
            for (Iterator i = rows.getChildren().iterator(); i.hasNext(); ) {
               final Row row = (Row) i.next();
               final Customer customer = (Customer) row.getValue();
               Button btnEdit = (Button) row.getChildren().get(3);
                  btnEdit.setDisabled(hasPermissions(customer));
               }
            }
      });
   }
}

The event onInitRender is triggered when the component gridCustomers starts to be rendered. At this time, none of its subcomponents have been rendered yet, so any attempt of modifying any element within gridCustomers will result into an error, gridCustomers.renderAll() forces its children subcomponents to be rendered, making it possible to modify any element within gridCustomers. After that, the code above fetches the 4th column, btnEdit, for every row and set its attribute disabled to the value returned by the function hasPermissions(customer). With this little trick, the problem has been solved.

Leaning on ZUL code can really fast your development pace and increase your productivity, besides leaving your code cleaner and easier to understand. However, sometimes it’s not possible to code an UI just by using ZUL, so a Renderer may be required. This solution shows how it’s possible to still use ZUL code while relying on some Java code for doing the hard parts, avoiding all the trouble of coding a Renderer.

Categories: igalia, java Tags:

The Myths of Innovation

March 1st, 2010 dpino No comments

Today I’ve just finished reading “The Myths of Innovation” by Scott Berkun published by O’Reilly (2007). It’s in fact a slim book, less than 200  pages, but a perfect accompanying reading for an idle weekend. I flickered it through a long time ago and really wanted to get my teeth into it, but I never found the time. After having reading it, I can only say it is absolutely worth.

The Myths of Innovation explores the ideas and misconceptions who most of us have about how innovation happens. Maybe it’s nothing new (neither innovative ideas are always totally brand-new), but the approach of the book, giving many real examples and providing a quite extensive list of references and quotes, makes it very easy and enjoyable to read.

There are many ideas and concepts exposed all along the book, but if I had to pick three of them, three ideas I would like to get stuck into my mind and be never forgotten, I will pick these three:

Innovation is not a single process, there’s no spark of geniality, no magical moment. Innovation, in fact, is a long process which tends to rely on the sum of other previous little innovations, every step is important to nurture the final result which is what we tend to retain in our minds as the truly innovation. The invention of the television is a great example. What is more important, who got the idea of using wires to send images through; the person who suggested using cathodic tubes to render images; or the person who finally made the first TV set and successfully commercialized it. All of them played a key role in the invention of television, but as history is linear and therefore deceptive, we tend to praise those who fits the last piece.

The list of idea-killers

Regarding the process of bringing up new ideas (brain-storming most of the times), Berkun compiles a list of silly arguments, but in fact often heard during brain-stormings. The list made laugh as I could  recognized having heart many of them other times, or even tell them myself, concluding how much stupid human beings can be. Here is the list:

  • We tried that already.
  • We’ve never done that before.
  • We don’t do it that way here.
  • That never works.
  • Not in our budget.
  • Not an interesting problem.
  • We don’t have time.
  • Executives will never go for it.
  • It’s out of scope.
  • People won’t like it.
  • It won’t make enough money.
  • How stupid are you?
  • You’re smarter with your mouth shut.

Refrain to say any of this in your next brain-storming meeting. If nothing controversial, weird, or embarrassing is said in a brainstorming session, you can tell the brainstorming is not working.

Good is not the enemy of the best

“Good is the enemy of the best”, Voltaire. When I heard it the first time, I though it was a very clever and insightful quote. I believed in the idea that good-enough software was in fact a lame excuse for not doing excellent software, but I may change my perspective after reading what Burken thinks about the statement above. Berkun explains how concepts like the hypertext, object-oriented languages or user interfaces were already invented in the 60 and 70 but didn’t go mainstream, and by hence they were not successful till much years later. In the case of hypertext, Ted Nelson is well-known for openly criticizing the web as it’s today, something he considers much inferior to his original idea of what the web should be. Although Sir Tim Berners Lee may have dropped many of his ideas on his way to implement the first version of the web (HTML, HTTP,  first web server and first limited browser), perhaps he would have never make it if he hadn’t discarded or ignored many of Nelson’s ideas (not on purpose, but driven by the fact of events). Having not doing so, perhaps he had also failed. One of the strongest points of Berners-Lee was focusing really on the things he wanted to solve. He might foresee the upcoming importance of digital media on the web (specially images at that time) but he preferred to just focus on text instead, hence simplifying the problem he was trying to solve. You don’t need to make a product perfect before releasing the first time.

It’s a powerful idea in fact. Apple does this all time, and quite well in my opinion. Under the mantra “focus in the user experience”, many Apple products lack features which would be very easy to implement. I’m thinking of Apple TV for instance (not a very successful product, but illustrates quite well what I mean). When I tried Apple TV the first time I loved it, but as I played with it I asked myself “Why they haven’t include this and that, it would be very easy to do”. My friend responded me: “Yes, maybe they could, but that will make it more difficult to use for the average user” (heighten the barrier of penetration). Linux programs and commands are full of options and parameters which make them very powerful (and geeky), but more difficult to use as well. No wonder why Linux hasn’t yet conquered the desktop, and might never do, as most of the programmers who contribute and make the Linux operating system want powerful tools, not easy-to-use tools.

Other interesting ideas are: Don’t spend your whole time into one single thing, innovating involves hard-working but also being idle. Exploring other fields can help you to apply old concepts from other areas of knowledge to areas where they are new (examples of this are the birth of the spreadsheet, or Google’s search engine); How innovate ideas need time to be nurtured and explored, don’t pick one idea to focus in the beginning, but rather pick several simultaneously and see where they bring you; Defining a problem is 90% of the work of defining a solution (with a great example of the Palm Pilot); Exploring and finding a solution can lead to new interesting paths and finally change the goal of the problem your were trying to solve (as in the birth of Flickr, initially though as a complementary software for a video-game); Life is a zero-sum game, and the resources for innovation must come at the expense of something else.

Categories: philosophy Tags:

I18n ZK framework ZUL pages using GNU Gettext

September 19th, 2009 dpino No comments

Since ZK 2.2.0 is possible to add i18n support by using i3-label*.properties files to store localized strings and use resource class Labels to retrieve them. This approach is the most extended in ZK for localizing ZUL files, and it was introduced by Minjie Zha in his smalltalk “I18N Implementation in ZK”.

However, this approach has its drawbacks. It requires developers to think first of a key for the text they are going to localize, store it in a i3-label*.properties file together with the localized text, an enable the mechanisms necessary to retrieve keys from a ZUL file. In addition, ZUL files are flooded with keys which sometimes have an obscure meaning.

GNU Gettext utilities follow a similar approach, but with the clear advantage of saving developers the burden of thinking of a key. Developers simply write down text in their source files as they would normally do, together with Gettext utilities, that very same text will serve as a key for all localized texts.

On my previous posts I gave a brief introduction to GNU gettext, how to settup Getttext Commons in a Java enviroment, and how to use Gettext from a Java project. Before going ahead with this post, I recommend you to take a look at those articles in case you haven’t done that yet, as from here on I will refer to some of the concepts and examples explained on them.

First of all, check you have sucessfully installed and configured Gettext Commons in your project.

Now what we are going to modify I18nHelper.java class explained on my last post. I am not going to get very much in detail here, what I am basically going to do is to modify getI18n() method so it knows through ZK engine which Locales end-user is asking for, loading it in case it exists, or using a default one (Click to download final version of I18nHelper.java).

After that we are going to create a taglib which is simply a facade for I18nHelper.

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?>
<taglib>
    <uri>http://com.igalia/i18n</uri>
    <description></description>
    <function>
        <name>_</name>
        <function-class>com.igalia.I18nHelper</function-class>
        <function-signature>
            java.lang.String _(java.lang.String name)
        </function-signature>
        <description></description>
    </function>
</taglib>

Name it i18n.tld and save it under your /WEB-INF/tld/ directory (Click to download i18n.tld).

After that, you are ready to include i18n.tld taglib from a ZUL file. Include it and use the i18n prefix accordingly. For instance,

<zk>
    < ?taglib uri="/WEB-INF/tld/i18n.tld" prefix="i18n" ?>
    <window>
        <button label="${i18n:_('Add')}" />
    </window>
</zk>

Load it on your favorite browser and see what happens. Basically what we are doing here is to rely on I18nHelper, which exposes a _ function for localizing strings passed as parameter. I18nHelper works against a specific resource bundle, a binary file compiled as the result of a gettext process. A resource bundle contains localized strings and knows how to convert msgids, or keys, to locale strings.

As you may have seen in Using Gettext Commons from Java files, localizing strings in Java files was an easy task. We used GNU Gettext utilities to parse down Java files, searching for strings marked with the _ function. The text within this function served as a key for generating a keys.pot file. Later that file was localized to a locale.po, es.po (Spanish localized file, for instance), and with the help of msgfmt command was possible to generate a resource bundle that could be used later from Java files for localizing texts dinamically. This same philllosophy applies to the process of localizing ZUL files.

The first obstacle that we need to surpass to generate a resource bundle successfully is parsing ZUL files searching for texts wrapped by ${i18n:_(‘%s’)}. GNU gettext utilities support a myriad of programming languages but unfortunately gettext does not support XML files. However, this is not a problem as parsing a XML file is much easier than parsing source code of a programming language. I wrote a small Perl script: gettext_zul.pl, which does exactly that. Run it like this:

gettext_zul.pl --dir path_to_zul_files --keys existing_keys.pot_file

You can ommit the –keys parameter, so a new keys.pot will be created in your current directory. This option can be useful in case you have an existing keys.pot file, generated prior as the result of processing a set of Java files for example.

Once your keys.pot file is up-to-date, create a localized version out of it (See I18n with GNU Gettext utilities). Lastly, run msgfmt to generate a locale resource bundle, Messages_XX.class, out of locale.po.

Supporting arguments

Generally text messages need extra parameters. For example, message “Confirm deleting element?” should be localized as ‘”Confirm deleting {0}?”, item.name’. To sort out this problem, we can extend I18nHelper and overload _ method with extra arguments.

public static String _(String str) {
return getI18n().tr(str);
}
 
public static String _(String text, Object o1) {
return getI18n().tr(text, o1);
}
 
public static String _(String text, Object o1, Object o2) {
return getI18n().tr(text, o1, o2);
}
 
public static String _(String text, Object o1, Object o2, Object o3) {
return getI18n().tr(text, o1, o2, o3);
}
 
public static String _(String text, Object o1, Object o2, Object o3,
Object o4) {
return getI18n().tr(text, o1, o2, o3, o4);
}
 
public static String _(String text, Object[] objects) {
return getI18n().tr(text, objects);
}

To make use of these new functions, we need to exposed them in i18n.tld tag-lib. Tag libs do not support function overloading, so we need to provide different names for each function. For instance, we may add a new function, __, that receives one extra parameter.

<function>
    <name>__</name>
    <function-class>com.igalia.I18nHelper</function-class>
    <function-signature>
        java.lang.String _(java.lang.String name, java.lang.Object arg0)
    </function-signature>
    <description></description>
</function>

I18n as a Macrocomponent

Another way of supporting arguments from ZUL files is to encapsulate I18nHelper funcionality into a Macrocomponent.

First of all, create a HTMLMacroComponent, save it as i18n.zul at webapp/common/components/ (Click to download i18n.zul)

<zk>
    <label value="@{self.i18n}" />
</zk>

Create its corresponding Java file (Click to download I18n.java) and save it as I18n.java at webapp/common/components/

And finally add this new macrocomponent to your lang-addon.xml file.

<component>
    <component-name>i18n</component-name>
    <component-class>com.igalia.common.components.I18n</component-class>
    <macro-uri>/common/components/i18n.zul</macro-uri>
</component>

Now you are ready to use it from a ZUL page.

<i18n value="Confirm deleting {0} ?" arg0="@{item.name}"/>

Macrocomponent Vs Taglib

Most part of the time we may just need to localize values inside attributes, in this case using a tag-lib is the right way to go, for example:

<button label="${i18n:_('Accept')}"/>

Tag-libs are OK for static texts. Static texts are evaluated only once when the ZUL page is rendered for the first time. When showing texts with data bindings, we must use i18n macrocomponent. In most cases, strings with arguments have their arguments bound to dynamic data. As rule of thumb, whenever there are arguments, i18n macrocomponent is the right choice.

<i18n value="Confirm deleting {0} ?" arg0="@{item.name}"/>

However, enabling i18n to support a different number of arguments can be convenient if we need to substitute an argument inside a literal value. Consider the following example:

<window title="Error ${requestScope['javax.servlet.error.status_code']}"/>

This is a very particular case but it still can happen in your code. Adding an extra __ function in your taglib (see above) can solve this problem.

<window title="${i18n:__('Error', requestScope['javax.servlet.error.status_code'])}">
</window>

NOTE: Do not interpolate requestScope variable as it is already inside another interpolation (${i18n:…})

In this last chapter I have reviewed a new approach to internationalize texts in ZUL files. This approach is based on GNU gettext, probably the most wide-spread way of localizing texts in the FOSS world. This method provides clear advantages to developers as they do not need to spend time thinking of meaningless keys and keeping track of them manually across different localized files, which in the long-run means saving time and automatizing the whole process of translating and localizing.

Download all files on this post: i18n.tar.gz.

Categories: igalia, java, zk Tags:

Using Gettext Commons from Java files

September 5th, 2009 dpino No comments

On my previous posts I introduced GNU gettext utilities and showed how to setup Gettext Commons library for Java. In this new post, I’ll focus on how to use Gettext Commons library for i18n Java files.

The result of  tagging and post-processing source code using GNU gettext utilities is generally a binary file which can later be used from a target programming language. In Java, this binary file is called a resource bundle, with extension .class. There are as many resource bundle files as locale.po files exist in our application. For each locale, there’s a Messages_XX.class file. Basically, a resource bundle is a collection of msgids and its corresponding locale translations. Let’s see how it works:

class MyClass {
   I18n i18n = I18NFactory.getI18n(this.getClass(),
         new Locale("Es", "es"),
         org.xnap.commons.i18n.I18nFactory.FALLBACK);
 
   public void render() {
      Listheader listheader = new Listheader(i18n.tr("Header"));
   }
}

For i18n a text string in source code, we need to instantiate a I18n object before by calling I18NFactory.getI18(). This static method returns a specific resource bundle, depending on the calling paremeters. In the example above, I asked for a resource bundle for locale es_ES (Spanish language, Spanish dialect from Spain). The third parameter is a flag sign indicating that in case such resource bundle doesn’t exist a default resource bundle will be returned. A default resource bundle does actually nothing, it simply returns i18n marked strings as they are.

On the render() method, I wrapped “Resource” within a i18n.tr function. This function is used to mark texts to be internationalized. Later we should parametrized gettext command properly so it can recognize tr as a marker, and fetch msgids from it. On the other hand, typing i18n.tr every time we need to mark a text, plus instantiating a i18n object for every .java file,  can be tedious and repetitive. Fortunately, this can be improved:

public class I18nHelper {
I18n i18n = I18nFactory.getI18n(I18nHelper.class,
new Locale("Es", "es"),
 org.xnap.commons.i18n.I18nFactory.FALLBACK);
 
 public static String _(String str) {
 return i18n.tr(str);
}

So, later we just need to add a static import of _ from other Java file, and we’re ready to go (in case of using _ as marker, call xgettext with -k _)

import static org.navalplanner.web.I18nHelper._;
 
class MyClass {
   public void render() {
      Listheader listheader = new Listheader(_("Header"));
   }
}

In this post, I have reviewed how to use Gettext Commons java library for i18n strings spread across source code. On my next post, I will focus on the more specific case of i18n ZUL pages, UI XML files from ZK framework, using Gettext, of course ;-)

Categories: igalia, java Tags:

Setting up Gettext Commons for i18n Java files

August 30th, 2009 dpino No comments

In my previous post: I18n with GNU Gettext utilities, I covered the basis of GNU gettext utilities. In this new post, I’ll explain how to use gettext to internationalize .java files.

Gettext Commons is Java library that makes use of GNU gettext utilities. It will enable us to mark texts to be localized in source code as well as taking care of retrieving localized strings. So, we can think of Gettext Commons as a bridge between our project and MO (Message Object) files generated as result of a gettext workflow.

Gettext Commons comes as .jar. There’s even a Maven repository for it. So, if you’re running a Maven2 project, add the following lines to your POM file:

<repositories>
<!– Add Gettext commons repository –>
<repository>
<id>gettext-commons-site</id>
<url>http://gettext-commons.googlecode.com/svn/maven-repository</url>
</repository>
</repositories>
<dependencies>
<!– Add Gettext commons dependency –>
<dependency>
<groupId>org.xnap.commons</groupId>
<artifactId>gettext-commons</artifactId>
<version>0.9.6</version>
</dependency>
</dependencies>

Apart from gettext-commons.jar library, there’s also a Gettext Maven plugin. This plugin comes apart from the .jar library, and it’s not necessary for using gettext from Java.

Unfortunately Gettext Commons website documentarion is a bit outdated, lacking information about how to setup the plugin, latest version, and parameters for every goal. For installing the plugin add the following lines to your POM file:

<pluginRepositories>
<!– Add Gettext Maven plugin repository –>
<pluginRepository>
<id>gettext-commons-site</id>
<url>http://gettext-commons.googlecode.com/svn/maven-repository</url>
</pluginRepository>
</pluginRepositories>
<plugins>
<!– Add Gettext Maven plugin –>
<plugin>
<groupId>org.xnap.commons</groupId>
<artifactId>maven-gettext-plugin</artifactId>
<version>1.2.0</version>
<configuration>
<poDirectory>${project.build.sourceDirectory}/../resources/i18n</poDirectory>
<targetBundle>i18n.Messages</targetBundle>
<keywords>-k_</keywords>
</configuration>
</plugin>
</plugins>

Let’s check first how the plugin works. Gettext Maven plugin is basically a wrapper  of some GNU gettext commands: xgettext, msmerge and msgfmt. Run the following maven goals from command line to:

  • mvn gettext:gettext, parses .java files and generates keys.pot file.
  • mvn gettext:merge, executes previous command plus generates locale files (es.po, pt.po, jp.po, etc).
  • mvn gettext:dist, executes previous command plus generates a MO (Message Object) file, Messages_XX.class, for every locale file.

Each goal accepts a different range of parameters. Set parameters under &lt;configuration&gt; tag. In the example above, I’ve set up three parameters:

  • poDirectory, directory where to place locale files (.po files) as a result of executing mvn gettext:merge. ${project.build.sourceDirectory} is a predefined constant that points to the root folder of our project source code, usually src/main/java.
  • targetBundle, java package where to place MO files as a result of executing mvn gettext:dist. Bear in mind that a MO files are binary files, or in case of working with Java, .class files. The name of resulting MO files have the following format: Messages_XX.class, and they are stored at target/classes directory.
  • keywords, list of keywords used to mark texts in source code. In my case, I’ve used _ as a marker.

There’s even more parameters, but unfortunately I couldn’t find any piece of documentation which covered them. If you want to find out more, consider downloading the source code or take a look at it online. On the contrary, it’s well documented and easy to understand.

Notice that you don’t neccessary have to use gettext-maven-plugin to parse source code and generate MO files, you can still use GNU Gettext command-line utilities to do that. In addition, running mvn gettext:merge fails if target .po file doesn’t exist. Remember that:

msgmerge -U es.po keys.pot

just updates msgids from .pot file to .po file, it never creates a target .po file. For doing that you must run msginit (you can also copy .pot file to locale .po file, but you should remember to adjust the header to your needs, pay attention particularly to attribute charset).

So, basically in this post I’ve covered how to setup Gettext Commons library and Gettext Commons Maven plugin and how to use the latter in a Maven2 project. In my next post, I’ll focus exclusively on how to use Gettext Commons for i18n .java files.

Categories: igalia Tags:

The Web that wasn’t

August 23rd, 2009 dpino No comments

It seems to be an old video, but I just discovered it recently and I though it could be interesting to linked it here.

A masterly lecture by Alex Wright, author of “Glut: Mastering Information Through the Ages”, where he reviews the works of the early precursos of the Web: Eugene Garfield, Vannevar Bush, Ted Nelson, etc  and how their works has inspired and somehow shape the Web as we know it today. It came to my mind a Paul Baran quote I read once where he recognized that technology progress was accumulative, “If you don’t take care”, he said, “you may end up thinking you have done a big contribution, but in fact, every contribution relies on some other previous work”. Or to put it in Isaac Newton’s words “If I have seen further it is by standing on the shoulders of giants“. Enjoy!

Categories: web Tags:

I18n with GNU Gettext utilities

August 21st, 2009 dpino No comments

Recently I’ve been engaged addding internationalization support for a Java project running on top of ZK framework. It’s been a quite interesting experience, and I think it sharing my experience could be useful for other people facing similar problems. So this entry is planned to be a series of posts about internationalization (i18n hereafter). In this first post, I’ll explain what are the GNU gettext utilities and how to use them.

GNU gettext utilities are perhaps the most popular tools for i18n among free and open source projects. Basically, the idea is to mark text to be localized in the source code with some special tag. For instance:

Label lblName = new Label("First name");

Texts to be translated should be wrapped by gettext function which later will be called to retrieve a localized string.

Label lblName = new Label(gettext("First name"));

Generally, it could be convenient ro rename gettext as _ for shorten tags and make them easier to identify in the code.

public String gettext(String str) {
    return gettext(str);
}

There’s a basic set of steps or workflow when working with GNU gettex utilities. First, we mark our source code properly. Then we run command gettext command to parse those marks. The result will be a keys.pot file containing all texts prompt to be translated.

find ./src -name "*.java" -exec xgettext --from-code=utf-8 -k_ -o keys.pot '{}' \;

A keys.pot file has the following structure:

white-space
#  translator-comments
#. extracted-comments
#: reference...
#, flag...
#| msgid previous-untranslated-string
msgid untranslated-string
msgstr translated-string

A simple entry can look like this:

#: src/main/java/com/igalia/UnexpectedError.java:101
msgid "Run-time error"
msgstr "Error en tiempo de ejecución"

Every entry consists of its correspondant msgid, plus a list of comments containing  filename and line for every msgid that happened in the code. Considering that, it can be concluded that every msgid in a .pot file is in fact unique.

Once our keys.pot file has been generated, it’s time to localize it.You can simply copy keys.pot to your destination .po file (es.po, pt.po, jp.po, etc.), however the best way to do this is using msginit command:

msginit -l es_ES -o es.po -i keys.pot

In case a locale .po file already exists in our project, we can easily updated it by running the following command:

msgmerge -U es.po keys.pot

This will update all missing entries from .pot file to .po, so now you’re ready for translating new entries with poedit or your favorite text-editor.

Lastly, we need to turn the .po files into a machine-oriented format, which may yield efficient retrieval of translations by the programs of the package:

msgfmt --java2 -d . -r app.i18n.Messages -l es es.po

Please refer to GNU `gettext’ utilities: 10.1 Invoking the msgfmt Program for more details about parameters invocation.

In my next post, I’ll focus on how to use these tools to give i18n support to a Java project. Till then, have fun.

Categories: igalia, linux Tags:

Javascript: The Good Parts

July 26th, 2009 dpino No comments

There’s a sentence from Douglas Crockford speech “Javascript: The Good Parts”, which I found very clever and gave me some food for thought about what Javascript does actually mean for the Web today:

“Javascript is succeeding very well in an environment were Java was a total failure”

When Java was launched it was promised to be the language of the Internet basically because of the way programs were compiled and distributed, being able to run in every client machine where a JVM was available. Applets were the mantra of Java on its early years. Java visioneers foresee a future were programs will be downloaded and run on the client-side, downplaying the role of the server. On these days the idea of network computer also emerged, which interestingly has recently come back in the form of netbooks.

Mostly due to the lack of performance of applets, Sun dropped her attempt soon afterwards, coming with the idea of servlets and large collections of technologies focused on the server side. Ironically, Javascript, a language named after Java but that has nothing to do with it (Crockford speak got more on this), has succeeded over time on the idea of applets, as a sort of client-side application which brings rich user experience and interaction. And certainly the fact that Javascript is shipped on every browser gives it a huge potential over other RIA technologies such as a Flex or Silverlight. It’s in fact the most widespread programming language in the world, meaning it has the potential to reach the largest number of users. Given these facts, and counting  the huge improvements the language has gone through over the years (XHR, Json, firebug), plus the huge adoption of open standards, it comes at no surprise why Javascript has turned into one of the most important languages in the world nowadays.

By the way, after seeing what the Webkit team are doing with CSS and 3D transformations, I’m more convinced than ever that the future of RIA means Javascript and open web technologies (not counting the huge effort Google is investing on making Javascript the lingua-franca of the Web).

Lastly I cannot finish this post without recommending Cockford speech at Google Techtalks. It’s not only smart and eye-opener but witty and fun (I’m eager to read his book). There’re too many memorable quotes to put them all down here, definitively worth seeing it.

Categories: javascript Tags:

Hibernate mapping of a Java5 Enum

July 13th, 2009 dpino 1 comment

A quick search on Google returns lots of links on how to implement this, one at the topmost is about writing a helping class called EnumUserType.

This solution is outdated as new versions of Hibernate support JPA annotation @Enumerated. Using this former method is much simpler and therefore recommended.

Using @Enumeration annotation:

package org.navalplanner.business.resources.entities;

public enum Status {
BUSY,
AVAILABLE;
}
package org.navalplanner.business.resources.entities;

class MyClass {
@Enumeration(EnumType.VALUE)
private Status status;
}

In the example above, Status and MyClass should be stored in two separate files. Please notice that when doing the Hibernate mapping of class MyClass, if status access policy is set to property, an extra pair of get/set methods should be defined for class MyClass:

@Enumeration(EnumType.VALUE)
public Status getStatus {
return status;
}

@Enumeration(EnumType.VALUE)
public void setStatus(Status status) {
this.status = status;
}

However, I couldn’t get this working using annotations. I don’t know why, maybe hbm.xml definition and annotations cannot be mixed. So, I ended up translated this annotation to a hbm.xml file:

<class name="MyClass">
<id name="id">
<generator class="native"/>
</id>

<property name="status">
<type name="org.hibernate.type.EnumType">
<param name="enumClass">com.igalia.Status</param>
</type>
</property>
</class>

And that’s it!

Categories: igalia, java Tags:

Bad Behavior has blocked 22 access attempts in the last 7 days.