Happy (chinese) new year, everybody!

Welcome to the year of the pig.

Published 18/02/2007 at 06h32

Browsing through the local bookstores

I’ve been browsing through the local bookstores yesterday and have been looking through the programming and IT sections. The two big bookstores I’ve been in both still haven’t got a section for Ruby. There are sections for everything you might (or then, might not) be looking for, Perl, PHP, Python, Java, C#, Joomla, Mambo, ActionScript etc. At the first bookstore I found one book about Rails, the other had four or five. Both had them filed under general programming. Both did not have a single book about Ruby (“The Ruby Way”, the “Pickaxe”, nothing).

That makes me question:

  • How big is the acceptance of Ruby in Germany? and
  • How big is the acceptance of Rails in Germany?

I have seen a few articles about Rails in german language magazines, but I somehow have got the feeling, that Ruby and Rails haven’t yet arrived in Germany yet.

Am I right? Or do I just look in the wrong places? At least there are 139 people from Germany registered at workingwithrails (as of today).

Workingwithrails lists two other developers in Freiburg, Germany. Maybe three is enough to start a ruby brigade? We’ll see.

Published 18/02/2007 at 06h23

My thoughts about "JSF is way too complicated?"

Imho, JSF is not too complicated. JSF was conceived for specific goals, and I think that JSF matches these goals very well. When you want to develop a java web application and can follow the path that JSF has laid out for you, you are well served. Integration with IDEs is available, RAD support, drag and drop development, it’s all included in the package. So, yes, JSF is not too complicated, if you use it the way it should be used.

JSF, e. g. , abstracts away the low level request-response layer inherent in all applications delivered over HTTP. I agree with Tim Shadel that the abstraction is leaky, but maybe programmers new to web development have something to gain from this abstraction.

It is only when you leave the troten path, when you make design decisions that were not considered in JSF, that JSF gets complicated. And even then, it is not actually JSF that gets complicated, but the fact that you have to work around a framework which was supposed to help you. It gets complicated because you have to dig through the seven layer burrito down to the request and the response to do what you want to do. Managed beans in request scope and bookmarkable URLs are, in my experience, things that have either not been considered in JSF, have been omitted on purpose or were, to the JSF creators, on the fringe of things considered necessary for a web framework.

I have done web development in Java since about eight years, starting out with Servlets going over JSP to JSF. I have also done web development in Perl, PHP and Python. And I currently do all my off-work projects in rails. Having worked with different frameworks written in different languages, I feel like there is a sweetspot between abstraction and allowing easy access to low level HTTP. And that sweetspot surely isn’t universal. But it seems that I share the same sweetspot with a lot of programmers. For me it’s rails. BUT: that does not mean that I would say that JSF is bad! It is just not a the level of abstraction I would like to work at.

Published 18/02/2007 at 06h16

On the Move...

…that is, on this Move. This is what I spend a great deal of my time on:

Move

The one in the picture is our own Move, but I’m lucky to have one at the office as well. If you have the chance to test one of these chairs, do so. And take more time than just five minutes. This chair really keeps you in motion, even during long coding sessions. And that keeps the stress away from your back. Though it might lock like it should hurt to sit on a Move for more then 15 minutes, my back is relaxed even after ten hours.

Nonetheless, I wouldn’t say that you don’t have to do regular workout, even when you have one of these.

Published 12/02/2007 at 15h40

Gem Survey

In response to Mike Clark’s question, here is what I’ve got on my machine:

wei-fieg@nono ~ $ sudo gem list --local | grep '([0-9]\.'
actionmailer (1.3.2, 1.3.1)
actionpack (1.13.2, 1.13.1)
actionwebservice (1.2.2, 1.2.1)
activerecord (1.15.2, 1.15.1)
activesupport (1.4.1, 1.4.0)
acts_as_taggable (2.0.2)
ajax_scaffold_generator (3.1.11, 3.1.10)
capistrano (1.4.0, 1.3.1)
cheat (1.2.1)
coverage (0.3)
deprec (1.2.3, 1.2.1)
facets (1.8.20, 1.7.46)
ferret (0.10.14)
flickr (1.0.0)
highline (1.2.7, 1.2.5)
hoe (1.1.7)
log4r (1.0.5)
mocha (0.4.0)
model_security_generator (0.0.9)
mysql (2.7)
needle (1.3.0)
net-sftp (1.1.0)
net-ssh (1.0.10)
openid_login_generator (0.1)
rails (1.2.2, 1.2.1)
rake (0.7.1)
RedCloth (3.0.4)
ruby-activeldap (0.8.1)
ruby-openid (1.1.4)
ruby-yadis (0.3.4)
rubyforge (0.4.0)
RubyInline (3.6.2)
sources (0.0.1)
streamlined_generator (0.0.5)
tattle (1.0.1)
termios (0.9.4)
wirble (0.1.2)
xml-simple (1.0.10)

Hmm, the number matches that of Mike Clark’s list (but is really low compared to Chad Fowler’s), the individual gems don’t all match up, though. But then, diversification is a good thing.

Published 12/02/2007 at 03h17

JSF: DataTable and CommandLink

Like a lot of other programmers who are forced to work with JSF, I fell into THE TRAP!

If you are using ManagedBeans in request scope, you get problems with CommandLinks inside DataTables.

DataTables are one thing I really like about JSF, and CommandLinks often come in handy as well. But when you put a CommandLink inside a DataTable, e. g., to select the entry of the row in which the CommandLink is, you get bitten. That is, if you want ManagedBeans with request scope. The action which should be triggered by the CommandLink is never triggered, the page is simply rendered again.

The reason for this behaviour is that the DataTable modifies the id of the CommandLink during renderering, but the CommandLink does not know that it was rendererd with a different id. During the decoding of the request which was triggered by clicking the CommandLink, the ComandLinkRenderer looks at a hidden form parameter. If the value of that form parameter equals the id of the CommandLink, an action is queued. If not, nothing is done.

Since the DataTable changes the ids, the value of the hidden form parameter does not match the id of the CommandLink.

So I wrote my own CommandLinkRenderer, overwrote the decode method and patched it so that the id match up again. When I want a CommandLink in a DataTable, I then specify that it should use my CommandLinkRenderer.

Here is the source of the decode method:


     @Override
    public void decode(FacesContext context, UIComponent component)
    {
        if (context == null || component == null)
        {
            throw new NullPointerException(Util
                    .getExceptionMessageString(Util.NULL_PARAMETERS_ERROR_MESSAGE_ID));
        }

        if (log.isTraceEnabled())
        {
            log.trace("Begin decoding component " + component.getId());
        }

        UICommand command = (UICommand) component;

        // If the component is disabled, do not change the value of the
        // component, since its state cannot be changed.
        if (Util.componentIsDisabledOnReadonly(component))
        {
            if (log.isTraceEnabled())
            {
                log.trace("No decoding necessary since the component "
                        + component.getId() + " is disabled");
            }
            return;
        }

        String clientId = command.getClientId(context), paramName = getHiddenFieldName(
                context, command);
        Map requestParameterMap = context.getExternalContext()
                .getRequestParameterMap();
        String value = (String) requestParameterMap.get(paramName);
        clientId = clientId.substring(0, clientId.lastIndexOf(":"));
        value = value.substring(0, value.lastIndexOf(":"));
        if (value == null || value.equals("") || !clientId.equals(value))
        {
            return;
        }
        ActionEvent actionEvent = new ActionEvent(component);
        component.queueEvent(actionEvent);

        if (log.isDebugEnabled())
        {
            log.debug("This command resulted in form submission "
                    + " ActionEvent queued " + actionEvent);
        }
        if (log.isTraceEnabled())
        {
            log.trace("End decoding component " + component.getId());
        }
        return;
    }

The diff to the original method is:


diff CommandLinkRenderer.java PatchedCommandLinkRenderer.java
124a125,126
>       clientId = clientId.substring(0, clientId.lastIndexOf(":"));
>       value = value.substring(0, value.lastIndexOf(":"));

It works form me, maybe others get some benefit from it as well.

(P.S. this is crossposted to http://forum.java.sun.com/thread.jspa?threadID=5116147)

Published 07/02/2007 at 07h39

RSS