Showing posts with label waffle. Show all posts
Showing posts with label waffle. Show all posts

January 21, 2008

Waffle 1.0 released

I am very happy to announce that after many months of hard work the Waffle team has released version 1.0 of Waffle.

Some of Waffle's features include:

  • Zero XML configuration

  • Minimal annotations

  • Convention over configuration

  • Easy to develop and test with (simple POJOs)

  • Built in support for Dependency Injection

  • Easily extensible architecture


If you haven't tried Waffle I urge you to take a look and see what you've been missing. As always any comments or suggestion are appreciated.

Waffle: Java based web development doesn't have to suck.

September 17, 2007

Waffle and JRuby: Accessing parameters and attributes from request, session and servlet context

In the last post I quickly explained how easy it is to access a component registered with Waffle from your JRuby based controllers. Now we need to understand how to access GET and POST parameters in order service a visitor's request. This is easily done through the parameters variable (also aliased as params) on your Ruby based Controllers. This variable is a simple Hash, so looking up parameter values from your Actions as easy as:
def example_one
foo = params['foo'] # request parameter
return "<h1>FOO: #{foo}</h1>"
end

Accessing Request, Session and ServletContext attributes

It might also be useful to access attribute values from either javax.servlet.ServletRequest, javax.servlet.http.HttpSession or javax.servlet.ServletContext. This is, as you should expect, very easy to do. But Waffle automatically wraps each of these as a Ruby Hash. This provides the correct Ruby "feel" when writing your Actions. The following code snippet give an example of how you can access attribute values from each of the 3 contexts:
def example_two
foo = params['foo'] # request parameter
fuu = request['fuu'] # request attribute
bar = session['bar'] # session attribute
baz = application['baz'] # servlet context attribute
return "<h1>FOO: #{foo} FUU: #{fuu} BAR: #{bar} BAZ: #{baz}</h1>"
end
Additionally, you can also call any of the Java methods these instances provide (you are NOT limited to methods exposed by Hash).

Auto-resolve values

Now those of you familiar with Waffle realize that Waffle provides a built-in means to auto-resolve a variables value. Waffle will search each of the following (in order) until the value is found, otherwise null (or in the case of JRuby nil) will be returned:
  1. HttpServletRequest Parameter (HttpServletRequest.getParameter("foo"))
  2. HttpServletRequest Attribute (HttpServletRequest.getAttribute("foo"))
  3. HttpSession Attribute (HttpSession.getAttribute("foo"))
  4. ServletContext Attribute (ServletContext.getAttribute("foo"))
  5. return nil

So with that in mind we can simplify the previous example down to one line. Waffle will attempt to resolve the value of any unknown variable through this means. The following shows the previous method simplified because it relies on Waffle auto resolving each value:
def example_three
return "<h1>FOO: #{foo} FUU: #{fuu} BAR: #{bar} BAZ: #{baz}</h1>"
end
In my next blog post I'll begin discussing how you can integrate JSPs or even RHTML with your applications.

September 14, 2007

Waffle: How to access your Java components from your Ruby Actions.

In my last post I gave an overview of how you can easily integrate JRuby with Waffle. Now we will examine Ruby based controller in a bit more depth. Lets assume we have the following Waffle Registrar for our application:
public class MyRegistrar extends AbstractRubyAwareRegistrar {

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

@Override
public void application() {
register("the_dao", PersonDAOImpl.class);

registerRubyScript("person", "PersonController");
}
}

A DAO, PersonDAOImpl, is registered under the name "the_dao" and we have one Ruby based controller available. Now its probably safe to assume that this Ruby PersonController will need access to the DAO. Gaining access to this DAO from the controller is easy in Waffle, just call the locate method:
class PersonController

def index
@person_dao = locate(example.PersonDAO)

@people = @person_dao.findAll
render 'person.rhtml'
end

end

Notice that we were able to retrieve the DAO by its interface. Additionally, since this DAO was registered with a key you can use a convention to retrieve the component. The convention is "locate_<component key>", here is the same controller using the locate_ convention:
class PersonController

def index
@person_dao = locate_the_dao

@people = @person_dao.findAll
render 'person.rhtml'
end

end

As you can see this makes writing Ruby based Controllers/Actions with Waffle really easy. In my next post I'll detail how to access request parameter and context attributes with ease.

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.

May 22, 2007

Waffle Haus ...

Waffle is moving from SourceForge to Codehaus. Additionally, and more importantly Waffle and VRaptor teams have decided to join forces.

The Waffle web framework will provide the core architecture for this joint effort. As the first step we have has begun porting Waffle to Codehaus (renaming it to use org.codehaus.waffle package instead of com.thoughtworks.waffle). Next we will begin to gradually port features from VRaptor. The vision of this effort is to create a larger and more consolidated community around a lean web application framework which honours the least-common-denominator principle.

October 05, 2006

ParaNamer support in Waffle as an alternative to annotations

The latest release of Waffle (0.7) can now fully support ParaNamer as an alternative to annotations. ParaNamer provides "method parameter name access for versions of Java PRIOR TO Java 7.0". ParaNamer combined with Waffle will allow you to utilize your ActionMethod parameter names directly. In the example below Waffle will use "itemId" and "quantity" to resolve the arguments for the void removeFromCart(Long, int) action method.

public class ShoppingCartAction implements Serializable {  
...

// No annotation is necessary when utilizing ParaNamer
public void removeFromCart(Long itemId, int quantity) {
cart.remove(itemId, quantity);
}
}


For complete details on this please see the documentation on Waffle ActionMethods.

October 04, 2006

Describing Waffle with one picture

The Waffle team has been busy over the last few months adding features and simplifying the overall design. Much of the documentation has been updated to reflect these changes. Many times however, it is easier to describe something with a simple drawing or a picture. So have a look at the following to get a clear idea of what Waffle provides:

June 19, 2006

Waffle: define a default event in your Action

Waffle now provides a new DefaultEvent method level annotation for use in your Actions. This allows you to mark a particular method as the default event to fire when no other event was signalled. This is particularly useful when a user is directed to a page for the first time. Until now, the previous page was responsible for setting up for the page that preceeds it. Either that or all links within your application would be required to define exactly which event should be triggered through request parameters (e.g. "/application/myaction.htm?EVENT=init|{request}").

The following Action example (MyAction) has its init(HttpServletRequest) method annotated as the default event.

public class MyAction {
@DefaultEvent("{request}")
public void init(HttpServletRequest request) {
// ...
}
}

Notice the value "{request}" set on the DefaultEvent annotation. This provides a hint to Waffle to help it satisfy the method arguments. If you are familiar with Waffle you should realize that this is similar to how events are defined from Views. This in fact is not just similar it is identical. You can define the event arguments for the DefaultEvent annotation in the same way described in the Advanced Events section of the tutorial.

April 19, 2006

Waffle on TheServerSide.com

Waffle was recently posted on TheServerSide.com under the heading Another Rails-like web framework: Waffle. I was happy to see it posted and really appreciated the responses from those that are interested in Waffle.

I'm grateful for the comparison of Waffle to Ruby on Rails but Waffle is NOT a Java version of Rails. I think the only viable comparison I can make between Waffle and Ruby on Rails is:
  • convention based
  • simplicity
  • both take advantage of their respective languages
  • increased development productivity
Many, if not most, of the clients I consult at have made a significant investment in either Java or .NET (specifically C#) and for that reason alone Ruby on Rails is not a viable option. So next time you are about to begin work on a Java based web framework make sure you take a look at Waffle.

March 28, 2006

Tutorials for Waffle

I have been spending my free time updating Waffle with functionality and documentation. Two tutorials have been added to the Waffle web site which should provide a good overview of how to use Waffle and what makes it different.

The examples in the tutorials show how to use Waffle with JSP's. This was done based on feedback I have had when talking about Waffle with developers. At this point you should get latest Waffle code directly from subversion and build it with Maven 2.0.

I would appreciate any comments or feedback you could offer.

February 14, 2006

FreeMarker support in Waffle

I recently added FreeMarker support as another option for creating Views in Waffle. FreeMarker is very similar to Velocity but seems to be more powerful. One of the nice features of FreeMarker is that it will point out the errors in your scripts. Velocity basically ignores any problems you may have, while FreeMarker displays an error message directly in your html that pin-points (line and column number) where the problems is located. Additionally FreeMarker actually allows you to reference JSP tag libraries within your FreeMarker scripts. That should allows for some nice flexibility. Take a look at the FreeMarker Servlet Documentation for further details. And take look at Waffle to see how easy it is to create web frameworks when you don't have to learn a proprietary XML syntax or new UI language.

Next task is to document how to create Waffle application with JavaServer Pages (JSP).

January 12, 2006

Mmmm Waffles...

It's been a while since I posted a blog, but I have been busy working on a new open source project. A new web framework for use in java/j2ee web applications.

Yes, I know there are already a plethora of java web frameworks, but Waffle (which is the name of the web framework) is different. Honest.

I wanted to work with a web framework that supports POJO based Actions, Dependency Injection, and it has no dependency on XML configuration files. Applications built on Waffle will be easier to develop and test with than other java web frameworks. Plus, it's buzz word compliant already fitting nicely with AJAX. :-)

Please have a look at the documentation and send me feedback on any suggestion you may have for improving the documentation or the framework itself.