der kl@mmeraffe | ruby. java. development.

a developers guide to the world of code

Monday, July 31, 2006

Developing an IOC-Container for Dependency Injection Part II

Part I | Part II | Part III

Welcome to the second part. Today we want to define how our configuration file shall look and start with the implementation of our container.
Look at the config-file of my personal dreams:

<services>
 <service name="Customer" class="ioc.example.Customer">
  <property name="id" value="1">
  <property name="names" type="list" value="[12,15,16]">
  <property name="numbers" type="array" value="[a,b,c]">
  <property name="smallmap" type="map" value="[1:a,2:b,3:c]">
  <property reference="User">
  <property reference="Admin">
 </property>

 <service name="User" class="ioc.example.UserImpl">

 <service name="Admin" class="ioc.example.Admin">
  <property name="adminName" value="Sam">
 </property>
</service>

We call every injected class a service. For every service we provide a implementation class. A service can have properties. We don't want to be too extreme in the beginning, so we just want Strings, lists, arrays , maps and references to other classes (via ).
The Details for the configfile above:
Here we define a Bean for the concrete class ioc.example.Customer and mark it with the id Customer. We define some Properties for that Bean:
id is a property that we initialize with the value 1. The container should automatically set the correct type for every primitive. The second property, names, is a list that we initialize with the values 12, 15, 16. It should also be possible to use arrays (for the beginning they'll be automatically String[]) and maps, as you can see at the properties numbers and smallmap. Now to the interesting stuff: The properties User and Admin are referenced beans, defined below in the same file. the Container must take care of all the Dependency Injection Stuff.
As you can see, it shouldn't matter wether you are using a simple concrete class for injection or an implementation of an interface (UserImpl).

So how can we implement the container? First we define the Interface:

package ioc.container;

public interface IOCContainer {
  public Object getInstance(String id);
  public Object getInstanceByClass(String clazz);
  public Object getInstanceByClass(Class clazz);
}

What are we doing here? We need methods to retrieve the auto-wired objects. And we want to have the ability to get them via the name (the id) or the class/class name.

Here comes the Implementation of the Standard IOC Container:


01 /**
02 * Standard Implementation for the IOCContainer
03 */
04 public class IOCContainerStandardImpl implements IOCContainer {
05
06   Map services;
07   IOCConfig conf;
08
09   public IOCContainerStandardImpl(String config) {
10
11     //Read Configuration-XML
12     conf = new IOCConfigParser().parse(config);
13
14     //Create all Services
15     services = new IOCServiceFactory().createServices(conf);
16   }
17
18  /**
19   * Create an Instance with the
20   * id of this class
21   */
22   public Object getInstance(String id) {
23    return services.get(id);
24   }
25
26  /**
27   * Create an Instance with the class
28   */
29   public Object getInstanceByClass(Class clazz) {
30     return services.get(clazz.getName());
31   }
32
33  /**
34   * Create an Instance with the fully
35   * qualified name of the class
36   *
37   * @param clazz
38   * @return
39   */
40   public Object getInstanceByClass(String clazz) {
41     return services.get(clazz);
42   }
43 }


Lets dive into the details:
First, in line 12, we read an configuration xml (like the one above) and parse throught it with an IOCConfigParser class. Here we receive an presentation of our services. Maybe thats not necessary, but that way we can put the configuration in a state and fill it with information that makes it easier to create the "real" services afterwards.
At line 15 we use an IOCServiceFactory class to create all services. That means instantiation of the correct classes, filling them with startup values with correct types defined in the config-file and wiring them together. And this means lots of reflection of course ;-) The services (or the beans, pojos, objects, whatever) are stored as a map in an instance variable. The other methods just give the corresponding service to the caller.

But that should be enough for today. In part 3 we dive deeper and look whats behind the IOCContainer, the Factory and so on. Stay tuned.

add to del.icio.us | submit to digg | submit to reddit

Saturday, July 29, 2006

Ruby on Rails First Steps

add this article to del.icio.us

Ruby on Rails is a lightweight MVC Web-Framework, written completely in the ruby programming language. It depends heavily on its code generation philosophy, you can generate the whole directory tree for your project, including templates for your models, views and controllers. Rails doesn't rely to much on configuration files, its more "convention over configuration. So you can obey some rules (don't have to, but the u need config files) and rails is doing some amazing stuff automatically. Therefore, there are no ridiculous mapping files (customer.id maps to customer.id, doh!), rails maps automatically between the relative to the objectoriented world at the persistence layer.

But lets dive into a small example. Here, we want to build a small, maybe usefull application: a todo list system, where you can create todo-lists and add tasks to them. It should also be possible to change, delete or view your todos.

Technical details first: To use Rauls, we nee Ruby. Depending on your local operation system choose the corresponding download at the Ruby-Homepage. In most Linux-Dists you don't need that step because ruby is already installed.
To develop a database driven application, we need a database management system. Typically we choose MySql, its free and everybody knows it. Get ithere. When you are there, be sure to also download the MySQL Administrator, an easy to use front end for the mysql server.

After the installation we open a shell an use gem, the official Ruby package manager, to download and install Rails.
gem install rails --include-dependencies

Alright, now we can start. Lets create our project "todo".
rails todo

Rails now creates the whole directory tree. Later, all the generated and changed models, views and controllers are in the subdirectory "app".

Next we create a new database (schema) via the MySQL Administrator with the name "todo" including two tables:
lists (id, name, description)
todos (id, name, txt, list_id)

Ok, now we edit the file database.yml in the directory todo/config and set the right database properties. Thats pretty easy and all you have to do for this simple example.

The first steps are done, start the webserver:
ruby script/server

Now at http://localhost:3000 Rails shows that its runnning. Lets see what we can do with it.
Because we named our list-table "lists", Rauls knows, that a component "List" will map to it. Rails is pretty clever in that point, it understands plural forms of lots of english nouns (including things like "entries" and "entry"). Here we can see the motto "convention over configuration". We have some conventions to obey, but we don't need things like deployment descriptors an mapping files.

Lets generate model and controller for the component "List":
ruby script\generate model List

ruby script\generate controller List

Rails generates the stubs, helper-classes and unit-tests.

Now we edit the script list_controller.rb at the directory app/controller (clean naming, isn't it?) and write into the class:
scaffold :list

A click at http://localhost:3000/list/new shows us what real prototyping is: The CRUD (Create, Remove, Update, Destroy) functionality is there without us doing anything, just with one line of code.

Check out these websites and tutorials for more information:
Ruby on Rails Homepage
top 12 ruby on rails tutorials
onlamp.com tutorial for rails

add to del.icio.us | submit to digg | submit to reddit

Friday, July 28, 2006

News: Google starts Sourceforge alternative

Not beautiful but interesting, thats for sure!

code.google.com/hosting

add to del.icio.us | submit to digg | submit to reddit

Thursday, July 27, 2006

Developing an IOC-Container for Dependency Injection Part I

Part I | Part II | Part III

Before we start: If you don't know whats behind IOC and Dependeny Injection, then read Martin Fowlers Article or jump to Wikipedia.

A couple of months ago i played with lots of IOC-Containers out there. Two of them interested me in the long run: Spring and Picocontainer. Spring because of its clean concept (yeah, i know, sometimes xml sucks, but if you make it intuitive...) and Picocontainer because of its "lightweight" concept. But both of them have there drawbacks.

Picocontainer has great code, as you can expect it from the codehaus (the guys with groovy), but nearly zero documentation. Spring, on the other side, is far to big for small projects that like to have an IOC-Container. You can separate the Container in Spring from the O/R-Mapping and MVC Stuff, but its still big. And where would be the fun without writing an own Container?

So what do we want? I'd say, we like to have a really, really lightweight container implementation. It should be extendable and testable. For configuration (for the wiring-together) we use simple xml. Really simple.

To "see" what we want, we write a tiny Test:

First, we want to instantiate an IOC-Container with a given config-File. The IOC-Container should have an interface and an implementation class, so we can change the implementation later on if we want to.

IOCContainer ioc = new IOCContainerStandardImpl("example-config.xml");

Then we want to create an instance of a class via the container.

Customer customer = (Customer)ioc.getInstance("Customer");

Ok, lets test wether customer holds the correct object

customer.logik()


We don't want to tell the Container which implementation class (say, CustomerImpl) is behind the interface (Customer) via code, cause then you have to change the code every time you want to change your implementation. The implementation should be wired over a small, easy to mantain config-file, where you can change the implementation from the outside.

But that should be enough for the first part, the next will be up soon ;-)

add to del.icio.us | submit to digg | submit to reddit

Tuesday, July 25, 2006

Ruby and XML

Ruby has builtin-support for XML via the rexml-module. This module supports various types of XML-parsing (e.g. building trees, event based streaming,...). We'll try the DOM-like-tree, but don't be afraid - its absolutely not as horrible as working with the DOM api under java.

Now, we want to parse the titles from a given weblog. We gotta use 3 modules for that

require 'rexml/document'
require 'net/http'
require 'uri'

Just that we don't have to type REXML before every command, we include that class

include REXML

Reading data over http is pretty straightforward in ruby

url = 'http://danslog.blogspot.com/atom.xml'
data = Net::HTTP.get(URI.parse(url))


Thats all. But we want to parse, unmarshall and whatever the given xml data

doc = Document.new(data)

The variable doc now contains the DOM-like-tree. Lets do an each over the titles in the feed. You can use xpath for that (imho the best xml spec out there)

doc.root.elements.each("entry/title") do |element|
  p element.text
end

That should output something like this:

"Groovy and SOAP"
"Pattern: Good Citizen"
"Ruby on Rails"
"News: AJAX-Framework als Apache-Projekt vorgeschlagen"
"Picocontainer"

Of course, streaming rss-feeds is even easier with ruby streaming apis for, well, rss-feeds, but i wanted to show how easy it is to work with xml under ruby.

Here is the whole class:

require 'rexml/document'
require 'net/http'
require 'uri'

include REXML

class RSSTitleCheck
  def initialize
    url = 'http://danslog.blogspot.com/atom.xml'
    data = Net::HTTP.get(URI.parse(url))
    doc = Document.new(data)
    doc.root.elements.each("entry/title") do |element|
      p element.text
    end
  end
end

RSSTitleCheck.new


You can find more info about REXML and HTTP-Access for Ruby here:

rexml intro @ xml.com
rexml tutorial @ germane-software.com
networking libs @ rubycentral.com/book

add to del.icio.us | submit to digg | submit to reddit

Thursday, July 13, 2006

Groovy and SOAP

All right, i've never seen SOAP implemented as easy as this:

Write a groovy-Script like that:

class SOAPTest {
  String printMe(String name) {
    return "Hello "+ name
  }
}

Start a SOAP-Server:

import groovy.net.soap.SoapServer
def server = new SoapServer("localhost", 6980)
server.setNode("SOAPTest")
server.start()


And check it with a client:

import groovy.net.soap.SoapClient
def proxy = new SoapClient("http://localhost:6980/SOAPTest?wsdl")
def result = proxy.printMe("Johnny")

More Information at the Codehaus-Homepage:
Groovy and SOAP @ codehaus.org

add to del.icio.us | submit to digg | submit to reddit

Friday, July 07, 2006

Pattern: Good Citizen

Every good OO-Developer knews: couple your objects as loose as possible, I already mentioned a popular IOC-Container (PicoContainter, article)
Dan North and Aslak Hellesoy defined the pattern "Good Citizen", you can check it out at the PicoContainer-Homepage. It sets some Rules for "well designed" classes, like the Dependency Injection Pattern which is the basis for all the IOC-Frameworks out there.
Maybe not all the rules are my cup of tea (like the one with seperately defined return values like StringList.EMPY), but nevertheless, if everybody would only write "Good Citizens", there would be less headache for the everyday life of a developer...

to the Pattern@codehaus.org

add to del.icio.us | submit to digg | submit to reddit