September 12, 2007

Ever wish you could utilize Ruby from your Java based web applications?

Waffle, a Java based Web Framework, now provides built in support for JRuby. This will allow you to easily write your Controllers in Ruby. The integration is simple and straightforward, taking advantage of functionality Waffle provides (without being a Rails clone).

A key feature of Waffle has always been its pluggable architecture. From the beginning we believed that the default behavior defined by the Waffle team might not be suitable for every situation. Therefor Waffle was built following an Interface driven approach. Practically all of Waffle's built-in functionality can easily be extended or replaced. This design made integrating JRuby support quite easy. The next 3 steps give a brief overview of how to integrate JRuby support into your Waffle based applications.

Step 1 - configure Waffle to be "Ruby Aware"

Waffle avoids XML like the plague but we still need to have a web.xml for our applications. This web.xml is where we can take advantage of Waffle's pluggability. The following three context-param nodes need to be added to your applications web.xml. This alerts Waffle that a few of its foundational components should be replaced with alternate implementations.
<context-param>
<param-name>org.codehaus.waffle.context.ContextContainerFactory</param-name>
<param-value>org.codehaus.waffle.context.pico.RubyAwarePicoContextContainerFactory</param-value>
</context-param>
<context-param>
<param-name>org.codehaus.waffle.bind.DataBinder</param-name>
<param-value>org.codehaus.waffle.bind.RubyDataBinder</param-value>
</context-param>
<context-param>
<param-name>org.codehaus.waffle.controller.ControllerDefinitionFactory</param-name>
<param-value>org.codehaus.waffle.controller.RubyControllerDefinitionFactory</param-value>
</context-param>

Step 2 - Your application's Registrar should extended AbstractRubyAwareRegistrar. This exposes a new registration method to use within your Registrar ... registerRubyScript(String key, String className). See the example below:
public class MyRegistrar extends AbstractRubyAwareRegistrar {

public MyRegistrar(Registrar delegate) {
super(delegate);
}

@Override
public void application() {
registerRubyScript("foobar", "FooBar");
}
...
}

In this example the Ruby class named 'FooBar' will be exposed as a Controller under the name 'foobar' (e.g. http://localhost:8080/jruby/foobar.waffle).

Step 3
- Write your Ruby Controller class. Notice in the following example that your class does not need to extend or include anything.
class FooBar

def index # This is the default action
"<h1>Hello World</h1>"
end

end

And that is all the steps required to integrate JRuby within your Waffle Applications. In my next post I will uncover details on how to access registered components from your Ruby based controllers as well as explain the built in conventions that make writing Ruby controllers so easy.

No comments: