der kl@mmeraffe | ruby. java. development.

a developers guide to the world of code

Friday, September 01, 2006

Simple Atom Feed With Ruby

Its really simple, took me bout an hour :-) But it suits my needs, and i don't have to implement other libs then build in (not even xml, allright, i'm crazy). Its not fast, reliable or something, but i wanted to create an atom feed that shows the files from a directory.
Heres the code:

class Atomfeed
attr_accessor :title, :subtitle, :link, :updated, :authorname, :authoremail, :id, :entries

def initialize
@title = ""
@subtitle = ""
@link = "http://"
@updated = ""
@authorname = ""
@authoremail = ""
@id = ""
@entries = []
end

def create_feed
@xml = ""
@xml = @xml + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
@xml = @xml + "<title>" + @title + "</title>\n"
@xml = @xml + "<subtitle>"+@subtitle+"</subtitle>\n"
@xml = @xml + "<link href=\""+@link+"\"/>\n"
@xml = @xml + "<updated>"+@updated+"</updated>\n"
@xml = @xml + "<author>\n <name>"+@authorname+"</name>\n <email>"+@authoremail+"</email>\n </author>\n"
@xml = @xml + "<id>"+@id+"</id>\n"
@entries.each do |entry|
@xml = @xml + " <entry>\n"
@xml = @xml + " <title>"+entry.title+"</title>\n"
@xml = @xml + " <link href=\""+entry.link+"\"/>\n"
@xml = @xml + " <id>"+entry.id+"</id>\n"
@xml = @xml + " <updated>"+entry.updated+"</updated>\n"
@xml = @xml + " <summary>"+entry.summary+"</summary>\n"
@xml = @xml + " </entry>\n"
end
@xml = @xml + "</feed>"
end
end

class Entry
attr_accessor :title, :link, :id, :updated, :summary

def initialize
@title = ""
@link = "http://"
@id = ""
@updated = ""
@summary = ""
end
end


Thats it (Lots of stuff to refactor here, but - hey, it works). To use it, i just start a webrick httpserver and map an action to the create_feed method. Before that, i fill the Atomfeed / Entry objects:


require 'webrick'
include WEBrick

s = HTTPServer.new( :Port => 2000 )

class AtomServlet < HTTPServlet::AbstractServlet
def do_GET(req, res)
@directory = "c:\\dev"
Dir.chdir(@directory)
@files = Dir["*"]
feed = Atomfeed.new
feed.title = "New files"
feed.subtitle = "Yeah, new Files"
feed.updated = Time.now.to_s
feed.authorname = "dan"
feed.authoremail = "blub@nothing_here.com"
feed.id = "123456789"

@files.each do |file|
entry = Entry.new
entry.title = file.to_s
entry.link = "http://"+file.to_s
entry.id = file.to_s
entry.updated = "134"
entry.summary = "huuhu"
feed.entries.push(entry)
end

res.body = feed.create_feed
res['Content-Type'] = "text/html"
end
end

s.mount("/atom.xml", AtomServlet)
trap("INT"){ s.shutdown }
s.start



Most Information here doesn't make sense, but it shows all files in the working directory :-) ruby is so much fun!

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

Tuesday, August 15, 2006

Working with wsdl2r, soap4r and complex types

Ruby has great support for SOAP built in. Trivial calls at least. Look at this example:

require 'soap/rpc/driver'
stub = SOAP::RPC::Driver.new("http://localhost:8080",
"http://somenamespace.com")
stub.add_method('gimmeAString', 'a_string')
p stub.gimmeAString("huhu!")

Easy, isn't it? You just create a new Driver object by handing over the location of the web service and its namespace. After that you can add the method you want to call and invoke it. Thats it. At least at the "Example-Stage". I real life, you need to declare complex types and use basic authentication and stuff. How to do that?
With soap4r, the standard soap framework for ruby, comes a nice script called "wsdl2ruby.rb". Example:
./wsdl2ruby.rb --wsdl coolWSDLFile.wsdl --type client 

That generates the complex types and the whole driver class you need to access your web service. Well, in theory, as brendon wilson describes in his article (thats written a lot better than this one here :-)). Because wsdl2ruby (and the whole wsdl4r part of the soap4r framework) is still in alpha stage, you can't expect too much. In my case, it couldn't handle all the complex types, so i had to fix it manually. Its not too difficult. Once you've got a generated driver you can add all necessary complex types that are missing and use the driver like in the first example at the top of this article.

A complex type definition looks like this (taken from the soap4r documentation):

require 'soap/mapping'

SampleStructServiceNamespace = 'http://tempuri.org/sampleStructService'

class SampleStruct; include SOAP::Marshallable
attr_accessor :sampleArray
attr_accessor :date

def initialize
@sampleArray = SampleArray[ "cyclic", self ]
@date = DateTime.now
end

def wrap( rhs )
@sampleArray = SampleArray[ "wrap", rhs.dup ]
@date = DateTime.now
self
end
end

class SampleArray < Array; include SOAP::Marshallable
end

To use this struct, just use it as a type in the method-definition:
stub.add_method('anotherMethod', 'sampleStruct')

btw, soap4r comes bundled with lots of extremely helpfull examples for all kind of usages.

As of basic authentication, you need to install http-access2.

With an additional line of code,
stub.options["protocol.http.basic_auth"] 
<< ["ws_url", "username", "password"]

basic authentication is done. More Information on that at Chris McMahons Blog

The SOAP implementation in Ruby itself is great. It seems to be reliable and it is rubyish to code (i.e "easy"). The wsdl2ruby generator needs some more work (i tried a second wsdl file, but that too didn't work), but it helped me a lot to write a SOAP-driver for my specific web service.

Another nice tutorial is here.

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

Wednesday, August 09, 2006

Java Stack Traces

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

Tuesday, August 08, 2006

Rails: All those little things

Image you've got a List (or an Array or whatever you like to call it) with objects. Those are articles with lots of fields. And you want to sort this List by one of its fields.
One thing some love (or hate) bout ruby is its use of blocks. Some say they are the most powerful thing imaginable, some say doing 2.times {p blub} isn't that cool (maybe they are both wrong and right).
Whatever. To sort a List is not a nice task in lots of programming languages. But look at this:

articles.sort! do |a, b|
a.value <=> b.value
end

Got it? You tell the List to sort itself (by calling the sort-method and putting a block in it). The block uses a funny operator that return -1, 0 or 1, depending on which element is bigger. The method uses this information to sort the List.

Those are the little things why i really like to code in ruby (with or without rails)

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

Sunday, August 06, 2006

Going on with Rails

Yesterday i started coding a small web app involving rss, mysql and stuff. Of course i chose Rails to check out how rapid and clean its possible to implement what i wanted to. I haven't that much with Rails till now, just a little testing. But the last to days (well, just for a couple of hours) it was possible for me to implement the database model + O/R mapping, the views, the rss-feed-aggregation-logic and user-management. Without even knowing the pitfalls or tricks in Rails i've done all of this in less than 4 hours or something (with my brain thinking how to do the design. coding was a joke!).
In Rails its fast to implement a web app because:

1. The ActiveRecord-Stuff.
Tell your app which database you use, generate models for the tables. Thats it for O/R mapping. When u change a field in the db, ActiveRecord dynamically changes its behaviour. And its extremely intuitive. Imagine a table "Customer". What if you want to find all of your customers? Right, just do
Customer.find_all
(or, nowadays:
Customer.find(:all)
). You want to change the customer-id? Type
customer.id = 1

Want to save the changes? Type
customer.save

There is nothing you have to code for the db-model in Rails.

2. Use of Ruby
I wanted to read rss-feeds. Of course, you can do this in every language imaginable. But with Ruby, its a sure bet that its extremely easy. I used "FeedTools":
@feedxml = FeedTools::Feed.open(feed.address)

now you can use the feed as a plain old ruby object.

3. no config
For some it may be a drawback to follow the conventions of Rails. Using plural-forms for tables isn't something everybody likes (including me), but when you create a "Customers"-Table you just have to generate your model "Customer" to dynamically access it. Same with actions in the controller. Create a method "login" and a rhtml "login". Now you can jump to localhost:3000/login and everything is done for you. Maybe for bigger apps thats not perfect but its great for prototyping.

4. No code bloat or bloated framework
The written code is always in Ruby, so its never to long, easy to read and to maintain. Rails has lots of stuff you will find handy but doesn't come with every latest technology every java developer have to fight with ;-)

I'll code along over the next couple of weeks, if the final app is something interesting i'll post it here :-)

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

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