<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-20076456</id><updated>2011-12-19T01:31:40.389-08:00</updated><title type='text'>der kl@mmeraffe | ruby. java. development.</title><subtitle type='html'>a developers guide to the world of code</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>16</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-20076456.post-115710526379675771</id><published>2006-09-01T02:48:00.000-07:00</published><updated>2006-09-01T03:13:30.330-07:00</updated><title type='text'>Simple Atom Feed With Ruby</title><content type='html'>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.&lt;br /&gt;Heres the code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Atomfeed&lt;br /&gt;    attr_accessor :title, :subtitle, :link, :updated, :authorname, :authoremail, :id, :entries&lt;br /&gt;&lt;br /&gt;    def initialize&lt;br /&gt;        @title = ""&lt;br /&gt;        @subtitle = ""&lt;br /&gt;        @link = "http://"&lt;br /&gt;        @updated = ""&lt;br /&gt;        @authorname = ""&lt;br /&gt;        @authoremail = ""&lt;br /&gt;        @id = ""&lt;br /&gt;        @entries = []&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    def create_feed&lt;br /&gt;        @xml = ""&lt;br /&gt;        @xml = @xml + "&amp;lt;?xml version=\"1.0\" encoding=\"utf-8\"?&amp;gt;\n&amp;lt;feed xmlns=\"http://www.w3.org/2005/Atom\"&amp;gt;\n"&lt;br /&gt;        @xml = @xml + "&amp;lt;title&amp;gt;" + @title + "&amp;lt;/title&amp;gt;\n"&lt;br /&gt;        @xml = @xml + "&amp;lt;subtitle&amp;gt;"+@subtitle+"&amp;lt;/subtitle&amp;gt;\n"&lt;br /&gt;        @xml = @xml + "&amp;lt;link href=\""+@link+"\"/&amp;gt;\n"&lt;br /&gt;        @xml = @xml + "&amp;lt;updated&amp;gt;"+@updated+"&amp;lt;/updated&amp;gt;\n"&lt;br /&gt;        @xml = @xml + "&amp;lt;author&amp;gt;\n  &amp;lt;name&amp;gt;"+@authorname+"&amp;lt;/name&amp;gt;\n   &amp;lt;email&amp;gt;"+@authoremail+"&amp;lt;/email&amp;gt;\n &amp;lt;/author&amp;gt;\n"&lt;br /&gt;        @xml = @xml + "&amp;lt;id&amp;gt;"+@id+"&amp;lt;/id&amp;gt;\n"&lt;br /&gt;        @entries.each do |entry|&lt;br /&gt;            @xml = @xml + "    &amp;lt;entry&amp;gt;\n"&lt;br /&gt;            @xml = @xml + "        &amp;lt;title&amp;gt;"+entry.title+"&amp;lt;/title&amp;gt;\n"&lt;br /&gt;            @xml = @xml + "        &amp;lt;link href=\""+entry.link+"\"/&amp;gt;\n"&lt;br /&gt;            @xml = @xml + "        &amp;lt;id&amp;gt;"+entry.id+"&amp;lt;/id&amp;gt;\n"&lt;br /&gt;            @xml = @xml + "        &amp;lt;updated&amp;gt;"+entry.updated+"&amp;lt;/updated&amp;gt;\n"&lt;br /&gt;            @xml = @xml + "        &amp;lt;summary&amp;gt;"+entry.summary+"&amp;lt;/summary&amp;gt;\n"&lt;br /&gt;            @xml = @xml + "    &amp;lt;/entry&amp;gt;\n"&lt;br /&gt;        end&lt;br /&gt;        @xml = @xml + "&amp;lt;/feed&amp;gt;"&lt;br /&gt;    end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Entry&lt;br /&gt;    attr_accessor :title, :link, :id, :updated, :summary&lt;br /&gt;&lt;br /&gt;    def initialize&lt;br /&gt;        @title = ""&lt;br /&gt;        @link = "http://"&lt;br /&gt;        @id = ""&lt;br /&gt;        @updated = ""&lt;br /&gt;        @summary = ""&lt;br /&gt;    end    &lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require 'webrick'&lt;br /&gt;include WEBrick&lt;br /&gt;&lt;br /&gt;s = HTTPServer.new( :Port =&gt; 2000 )&lt;br /&gt;&lt;br /&gt;class AtomServlet &lt; HTTPServlet::AbstractServlet&lt;br /&gt;  def do_GET(req, res)&lt;br /&gt;    @directory = "c:\\dev"&lt;br /&gt;    Dir.chdir(@directory)&lt;br /&gt;    @files = Dir["*"]&lt;br /&gt;    feed = Atomfeed.new&lt;br /&gt;    feed.title = "New files"&lt;br /&gt;    feed.subtitle = "Yeah, new Files"&lt;br /&gt;    feed.updated = Time.now.to_s&lt;br /&gt;    feed.authorname = "dan"&lt;br /&gt;    feed.authoremail = "blub@nothing_here.com"&lt;br /&gt;    feed.id = "123456789"&lt;br /&gt;  &lt;br /&gt;    @files.each do |file|&lt;br /&gt;      entry = Entry.new&lt;br /&gt;      entry.title = file.to_s&lt;br /&gt;      entry.link = "http://"+file.to_s&lt;br /&gt;      entry.id = file.to_s&lt;br /&gt;      entry.updated = "134"&lt;br /&gt;      entry.summary = "huuhu"&lt;br /&gt;      feed.entries.push(entry)&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    res.body = feed.create_feed&lt;br /&gt;    res['Content-Type'] = "text/html"&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;s.mount("/atom.xml", AtomServlet)&lt;br /&gt;trap("INT"){ s.shutdown }&lt;br /&gt;s.start&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Most Information here doesn't make sense, but it shows all files in the working directory :-) ruby is so much fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-115710526379675771?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/115710526379675771/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=115710526379675771' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115710526379675771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115710526379675771'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2006/09/simple-atom-feed-with-ruby.html' title='Simple Atom Feed With Ruby'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-115567029300449551</id><published>2006-08-15T11:47:00.000-07:00</published><updated>2006-08-15T13:08:30.783-07:00</updated><title type='text'>Working with wsdl2r, soap4r and complex types</title><content type='html'>Ruby has great support for SOAP built in. Trivial calls at least. Look at this example:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require 'soap/rpc/driver'&lt;br /&gt;stub = SOAP::RPC::Driver.new("http://localhost:8080", &lt;br /&gt;  "http://somenamespace.com")&lt;br /&gt;stub.add_method('gimmeAString', 'a_string')&lt;br /&gt;p stub.gimmeAString("huhu!")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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?&lt;br /&gt;With &lt;a href="http://dev.ctor.org/soap4r"&gt;soap4r&lt;/a&gt;, the standard soap framework for ruby, comes a nice script called "wsdl2ruby.rb". Example:&lt;br /&gt;&lt;pre&gt;./wsdl2ruby.rb --wsdl coolWSDLFile.wsdl --type client &lt;/pre&gt;&lt;br /&gt;That generates the complex types and the whole driver class you need to access your web service. Well, in theory, as &lt;a href="http://www.brendonwilson.com/blog/2006/04/02/ruby-soap4r-wsdl-hell"&gt;brendon wilson&lt;/a&gt; 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.&lt;br /&gt;&lt;br /&gt;A complex type definition looks like this (taken from the soap4r documentation):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;require 'soap/mapping'&lt;br /&gt;&lt;br /&gt;SampleStructServiceNamespace = 'http://tempuri.org/sampleStructService'&lt;br /&gt;&lt;br /&gt;class SampleStruct; include SOAP::Marshallable&lt;br /&gt;  attr_accessor :sampleArray&lt;br /&gt;  attr_accessor :date&lt;br /&gt;&lt;br /&gt;  def initialize&lt;br /&gt;    @sampleArray = SampleArray[ "cyclic", self ]&lt;br /&gt;    @date = DateTime.now&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def wrap( rhs )&lt;br /&gt;    @sampleArray = SampleArray[ "wrap", rhs.dup ]&lt;br /&gt;    @date = DateTime.now&lt;br /&gt;    self&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class SampleArray &lt; Array; include SOAP::Marshallable&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To use this struct, just use it as a type in the method-definition:&lt;br /&gt;&lt;pre&gt;stub.add_method('anotherMethod', 'sampleStruct')&lt;/pre&gt;&lt;br /&gt;btw, soap4r comes bundled with lots of extremely helpfull examples for all kind of usages.&lt;br /&gt;&lt;br /&gt;As of basic authentication, you need to install &lt;a href="http://raa.ruby-lang.org/project/http-access2/"&gt;http-access2&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;With an additional line of code,&lt;br /&gt;&lt;pre&gt;stub.options["protocol.http.basic_auth"] &lt;br /&gt;  &lt;&lt; ["ws_url", "username", "password"]&lt;/pre&gt;&lt;br /&gt;basic authentication is done. More Information on that at &lt;a href="http://chrismcmahonsblog.blogspot.com/2006/03/soap-basic-authentication-in-ruby.html"&gt;Chris McMahons Blog&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Another nice tutorial is &lt;a href="http://www.devx.com/enterprise/Article/28101/1954?pf=true"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-115567029300449551?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/115567029300449551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=115567029300449551' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115567029300449551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115567029300449551'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2006/08/working-with-wsdl2r-soap4r-and-complex.html' title='Working with wsdl2r, soap4r and complex types'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-115513000961523264</id><published>2006-08-09T06:25:00.000-07:00</published><updated>2006-08-09T06:26:49.676-07:00</updated><title type='text'>Java Stack Traces</title><content type='html'>Funny. Sad. True.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ptrthomas.wordpress.com/2006/06/06/java-call-stack-from-http-upto-jdbc-as-a-picture/"&gt;Article bout Stack Traces @ ptrthomas.wordpress.com&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-115513000961523264?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/115513000961523264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=115513000961523264' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115513000961523264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115513000961523264'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2006/08/java-stack-traces.html' title='Java Stack Traces'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-115506652034154971</id><published>2006-08-08T12:36:00.000-07:00</published><updated>2006-08-08T12:48:40.356-07:00</updated><title type='text'>Rails: All those little things</title><content type='html'>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.&lt;br /&gt;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).&lt;br /&gt;Whatever. To sort a List is not a nice task in lots of programming languages. But look at this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;articles.sort! do |a, b|&lt;br /&gt; a.value &lt;=&gt; b.value&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Those are the little things why i really like to code in ruby (with or without rails)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-115506652034154971?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/115506652034154971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=115506652034154971' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115506652034154971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115506652034154971'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2006/08/rails-all-those-little-things.html' title='Rails: All those little things'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-115490053792677463</id><published>2006-08-06T14:26:00.000-07:00</published><updated>2006-08-06T14:42:25.136-07:00</updated><title type='text'>Going on with Rails</title><content type='html'>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!).&lt;br /&gt;In Rails its fast to implement a web app because:&lt;br /&gt;&lt;br /&gt;1. &lt;b&gt;The ActiveRecord-Stuff. &lt;/b&gt;&lt;br /&gt;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 &lt;pre&gt;Customer.find_all&lt;/pre&gt; (or, nowadays: &lt;pre&gt;Customer.find(:all)&lt;/pre&gt;). You want to change the customer-id? Type &lt;br /&gt;&lt;pre&gt;customer.id = 1&lt;/pre&gt;&lt;br /&gt;Want to save the changes? Type&lt;br /&gt;&lt;pre&gt;customer.save&lt;/pre&gt;&lt;br /&gt;There is nothing you have to code for the db-model in Rails.&lt;br /&gt;&lt;br /&gt;2. &lt;b&gt;Use of Ruby&lt;/b&gt;&lt;br /&gt;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":&lt;br /&gt;&lt;pre&gt;@feedxml = FeedTools::Feed.open(feed.address)&lt;/pre&gt;&lt;br /&gt;now you can use the feed as a plain old ruby object.&lt;br /&gt;&lt;br /&gt;3. &lt;b&gt;no config&lt;/b&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;4. &lt;b&gt;No code bloat or bloated framework&lt;/b&gt;&lt;br /&gt;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 ;-)&lt;br /&gt;&lt;br /&gt;I'll code along over the next couple of weeks, if the final app is something interesting i'll post it here :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-115490053792677463?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/115490053792677463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=115490053792677463' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115490053792677463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115490053792677463'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2006/08/going-on-with-rails.html' title='Going on with Rails'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-115403354196228591</id><published>2006-07-31T13:21:00.000-07:00</published><updated>2006-08-01T13:20:43.353-07:00</updated><title type='text'>Developing an IOC-Container for Dependency Injection Part II</title><content type='html'>&lt;a href="http://derklammeraffe.blogspot.com/2006/07/developing-ioc-container-for.html"&gt;Part I&lt;/a&gt; | Part II | Part III&lt;br /&gt;&lt;br /&gt;Welcome to the second part. Today we want to define how our configuration file shall look and start with the implementation of our container.&lt;br /&gt;Look at the config-file of my personal dreams:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;services&gt;&lt;br /&gt;&amp;nbsp;&amp;lt;service name="Customer" class="ioc.example.Customer"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property name="id" value="1"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property name="names" type="list" value="[12,15,16]"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property name="numbers" type="array" value="[a,b,c]"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property name="smallmap" type="map" value="[1:a,2:b,3:c]"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property reference="User"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property reference="Admin"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;lt;service name="User" class="ioc.example.UserImpl"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;lt;service name="Admin" class="ioc.example.Admin"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;property name="adminName" value="Sam"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/service&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;We call every injected class a &lt;span style="font-style: italic;"&gt;service&lt;/span&gt;. For every service we provide a implementation class. A &lt;span style="font-style: italic;"&gt;service &lt;/span&gt;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 &lt;property reference=".."&gt;).&lt;br /&gt;The Details for the configfile above:&lt;br /&gt;Here we define a Bean for the concrete class &lt;span style="font-style: italic;"&gt;ioc.example.Customer&lt;/span&gt; and mark it with the id &lt;span style="font-style: italic;"&gt;Customer&lt;/span&gt;. We define some Properties for that Bean:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;id&lt;/span&gt; is a property that we initialize with the value 1. The container should automatically set the correct type for every primitive. The second property, &lt;span style="font-style: italic;"&gt;names&lt;/span&gt;, 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.&lt;br /&gt;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).&lt;br /&gt;&lt;br /&gt;So how can we implement the container? First we define the Interface:&lt;br /&gt;&lt;code class=“source“&gt;&lt;br /&gt;package ioc.container;&lt;br /&gt;&lt;br /&gt;public interface IOCContainer {&lt;br /&gt;&amp;nbsp;&amp;nbsp;public Object getInstance(String id);&lt;br /&gt;&amp;nbsp;&amp;nbsp;public Object getInstanceByClass(String clazz);&lt;br /&gt;&amp;nbsp;&amp;nbsp;public Object getInstanceByClass(Class clazz);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;Here comes the Implementation of the Standard IOC Container:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;01&amp;nbsp;/**&lt;br /&gt;02&amp;nbsp;* Standard Implementation for the IOCContainer&lt;br /&gt;03&amp;nbsp;*/&lt;br /&gt;04&amp;nbsp;public class IOCContainerStandardImpl implements IOCContainer {&lt;br /&gt;05    &lt;br /&gt;06&amp;nbsp;&amp;nbsp;&amp;nbsp;Map services;&lt;br /&gt;07&amp;nbsp;&amp;nbsp;&amp;nbsp;IOCConfig conf;&lt;br /&gt;08    &lt;br /&gt;09&amp;nbsp;&amp;nbsp;&amp;nbsp;public IOCContainerStandardImpl(String config) {&lt;br /&gt;10        &lt;br /&gt;11&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Read Configuration-XML&lt;br /&gt;12&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;conf = new IOCConfigParser().parse(config);&lt;br /&gt;13        &lt;br /&gt;14&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//Create all Services&lt;br /&gt;15&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;services = new IOCServiceFactory().createServices(conf);&lt;br /&gt;16&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;17    &lt;br /&gt;18&amp;nbsp;&amp;nbsp;/**&lt;br /&gt;19&amp;nbsp;&amp;nbsp;&amp;nbsp;* Create an Instance with the &lt;br /&gt;20&amp;nbsp;&amp;nbsp;&amp;nbsp;* id of this class&lt;br /&gt;21&amp;nbsp;&amp;nbsp;&amp;nbsp;*/&lt;br /&gt;22&amp;nbsp;&amp;nbsp;&amp;nbsp;public Object getInstance(String id) {&lt;br /&gt;23&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return services.get(id);&lt;br /&gt;24&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;25    &lt;br /&gt;26&amp;nbsp;&amp;nbsp;/**&lt;br /&gt;27&amp;nbsp;&amp;nbsp;&amp;nbsp;* Create an Instance with the class&lt;br /&gt;28&amp;nbsp;&amp;nbsp;&amp;nbsp;*/&lt;br /&gt;29&amp;nbsp;&amp;nbsp;&amp;nbsp;public Object getInstanceByClass(Class clazz) {&lt;br /&gt;30&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return services.get(clazz.getName());&lt;br /&gt;31&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;32    &lt;br /&gt;33&amp;nbsp;&amp;nbsp;/**&lt;br /&gt;34&amp;nbsp;&amp;nbsp;&amp;nbsp;* Create an Instance with the fully&lt;br /&gt;35&amp;nbsp;&amp;nbsp;&amp;nbsp;* qualified name of the class&lt;br /&gt;36&amp;nbsp;&amp;nbsp;&amp;nbsp;* &lt;br /&gt;37&amp;nbsp;&amp;nbsp;&amp;nbsp;* @param clazz&lt;br /&gt;38&amp;nbsp;&amp;nbsp;&amp;nbsp;* @return&lt;br /&gt;39&amp;nbsp;&amp;nbsp;&amp;nbsp;*/&lt;br /&gt;40&amp;nbsp;&amp;nbsp;&amp;nbsp;public Object getInstanceByClass(String clazz) {&lt;br /&gt;41&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return services.get(clazz);&lt;br /&gt;42&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;43&amp;nbsp;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Lets dive into the details:&lt;br /&gt;First, in line 12, we read an configuration xml (like the one above) and parse throught it with an &lt;span style="font-style:italic;"&gt;IOCConfigParser&lt;/span&gt; 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. &lt;br /&gt;At line 15 we use an &lt;span style="font-style:italic;"&gt;IOCServiceFactory &lt;/span&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-115403354196228591?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/115403354196228591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=115403354196228591' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115403354196228591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115403354196228591'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2006/07/developing-ioc-container-for_31.html' title='Developing an IOC-Container for Dependency Injection Part II'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-115418552434550684</id><published>2006-07-29T08:04:00.000-07:00</published><updated>2006-08-01T13:20:58.396-07:00</updated><title type='text'>Ruby on Rails First Steps</title><content type='html'>&lt;a href="http://del.icio.us/post" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http://derklammeraffe.blogspot.com/2006/07/ruby-on-rails-first-steps.html&amp;title='+encodeURIComponent(document.title), 'delicious','toolbar=no,width=700,height=400'); return false;"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/983/744/400/delicious_s.0.gif" border="0" alt="" /&gt; add this article to del.icio.us&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Technical details first: To use Rauls, we nee Ruby. Depending on your local operation system choose the corresponding download at the &lt;a ref="http://ruby-lang.org"&gt;Ruby-Homepage&lt;/a&gt;. In most Linux-Dists you don't need that step because ruby is already installed. &lt;br /&gt;To develop a database driven application, we need a database management system. Typically we choose MySql, its free and everybody knows it. Get it&lt;a href="http://www.mysql.com"&gt;here&lt;/a&gt;. When you are there, be sure to also download the MySQL Administrator, an easy to use front end for the mysql server.&lt;br /&gt;&lt;br /&gt;After the installation we open a shell an use gem, the official Ruby package manager, to download and install Rails.&lt;br /&gt;&lt;pre&gt;gem install rails --include-dependencies&lt;/pre&gt;&lt;br /&gt;Alright, now we can start. Lets create our project "todo".&lt;br /&gt;&lt;pre&gt;rails todo&lt;/pre&gt;&lt;br /&gt;Rails now creates the whole directory tree. Later, all the generated and changed models, views and controllers are in the subdirectory "app".&lt;br /&gt;&lt;br /&gt;Next we create a new database (schema) via the MySQL Administrator with the name "todo" including two tables:&lt;br /&gt;&lt;pre&gt;lists (id, name, description)&lt;br /&gt;todos (id, name, txt, list_id)&lt;/pre&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;The first steps are done, start the webserver:&lt;br /&gt;&lt;pre&gt;ruby script/server&lt;/pre&gt;&lt;br /&gt;Now at &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt; Rails shows that its runnning. Lets see what we can do with it.&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Lets generate model and controller for the component "List":&lt;br /&gt;&lt;pre&gt;ruby script\generate model List&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;ruby script\generate controller List&lt;/pre&gt;&lt;br /&gt;Rails generates the stubs, helper-classes and unit-tests.&lt;br /&gt;&lt;br /&gt;Now we edit the script list_controller.rb at the directory app/controller (clean naming, isn't it?) and write into the class:&lt;br /&gt;&lt;pre&gt;scaffold :list&lt;/pre&gt;&lt;br /&gt;A click at &lt;a href="http://localhost:3000/list/new"&gt;http://localhost:3000/list/new&lt;/a&gt; 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.&lt;br /&gt;&lt;br /&gt;Check out these websites and tutorials for more information:&lt;br /&gt;&lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails Homepage&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.digitalmediaminute.com/article/1816/top-ruby-on-rails-tutorials"&gt;top 12 ruby on rails tutorials&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html"&gt;onlamp.com tutorial for rails&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-115418552434550684?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/115418552434550684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=115418552434550684' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115418552434550684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115418552434550684'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2006/07/ruby-on-rails-first-steps.html' title='Ruby on Rails First Steps'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-115407402384724828</id><published>2006-07-28T01:05:00.000-07:00</published><updated>2006-08-01T13:21:28.270-07:00</updated><title type='text'>News: Google starts Sourceforge alternative</title><content type='html'>Not beautiful but interesting, thats for sure!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/hosting/"&gt;code.google.com/hosting&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-115407402384724828?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/115407402384724828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=115407402384724828' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115407402384724828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115407402384724828'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2006/07/news-google-starts-sourceforge.html' title='News: Google starts Sourceforge alternative'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-115390023296300999</id><published>2006-07-27T00:49:00.000-07:00</published><updated>2006-08-01T13:21:44.896-07:00</updated><title type='text'>Developing an IOC-Container for Dependency Injection Part I</title><content type='html'>Part I | &lt;a href="http://derklammeraffe.blogspot.com/2006/07/developing-ioc-container-for_31.html"&gt;Part II&lt;/a&gt; | Part III&lt;br /&gt;&lt;br /&gt;Before we start: If you don't know whats behind IOC and Dependeny Injection, then read &lt;a href="http://www.martinfowler.com/articles/injection.html"&gt;Martin Fowlers Article&lt;/a&gt; or jump to &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection"&gt;Wikipedia&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Picocontainer has great code, as you can expect it from &lt;a href="http://codehaus.org"&gt;the codehaus&lt;/a&gt; (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?&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;To "see" what we want, we write a tiny Test:&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;IOCContainer ioc = new IOCContainerStandardImpl("example-config.xml");&lt;br /&gt;&lt;/code&gt;       &lt;br /&gt;Then we want to create an instance of a class via the container.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Customer customer = (Customer)ioc.getInstance("Customer");&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Ok, lets test wether customer holds the correct object&lt;br /&gt;&lt;code&gt;&lt;br /&gt;customer.logik()&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;But that should be enough for the first part, the next will be up soon ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-115390023296300999?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/115390023296300999/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=115390023296300999' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115390023296300999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115390023296300999'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2006/07/developing-ioc-container-for.html' title='Developing an IOC-Container for Dependency Injection Part I'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-115385950975880096</id><published>2006-07-25T13:15:00.000-07:00</published><updated>2006-08-01T13:22:00.890-07:00</updated><title type='text'>Ruby and XML</title><content type='html'>Ruby has builtin-support for XML via the &lt;code&gt;rexml&lt;/code&gt;-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.&lt;br /&gt;&lt;br /&gt;Now, we want to parse the titles from a given weblog. We gotta use 3 modules for that&lt;br /&gt;&lt;code&gt;&lt;br /&gt;require 'rexml/document'&lt;br /&gt;require 'net/http'&lt;br /&gt;require 'uri'&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Just that we don't have to type REXML before every command, we include that class&lt;br /&gt;&lt;code&gt;&lt;br /&gt;include REXML&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Reading data over http is pretty straightforward in ruby&lt;br /&gt;&lt;code&gt;&lt;br /&gt;url = 'http://danslog.blogspot.com/atom.xml'&lt;br /&gt;data = Net::HTTP.get(URI.parse(url))&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Thats all. But we want to parse, unmarshall and whatever the given xml data&lt;br /&gt;&lt;code&gt;&lt;br /&gt;doc = Document.new(data)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;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)&lt;br /&gt;&lt;code&gt;&lt;br /&gt;doc.root.elements.each("entry/title") do |element|&lt;br /&gt;&amp;nbsp;&amp;nbsp;p element.text&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;That should output something like this:&lt;br /&gt;&lt;br /&gt;"Groovy and SOAP"&lt;br /&gt;"Pattern: Good Citizen"&lt;br /&gt;"Ruby on Rails"&lt;br /&gt;"News: AJAX-Framework als Apache-Projekt vorgeschlagen"&lt;br /&gt;"Picocontainer"&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Here is the whole class:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;require 'rexml/document'&lt;br /&gt;require 'net/http'&lt;br /&gt;require 'uri'&lt;br /&gt;&lt;br /&gt;include REXML&lt;br /&gt;&lt;br /&gt;class RSSTitleCheck&lt;br /&gt;&amp;nbsp;&amp;nbsp;def initialize&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;url = 'http://danslog.blogspot.com/atom.xml'&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data = Net::HTTP.get(URI.parse(url))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;doc = Document.new(data)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;doc.root.elements.each("entry/title") do |element|&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p element.text&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;RSSTitleCheck.new&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You can find more info about REXML and HTTP-Access for Ruby here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.xml.com/pub/a/2005/11/09/rexml-processing-xml-in-ruby.html?page=1"&gt;rexml intro @ xml.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.germane-software.com/software/rexml/docs/tutorial.html"&gt;rexml tutorial @ germane-software.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.rubycentral.com/book/lib_network.html"&gt;networking libs @ rubycentral.com/book&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-115385950975880096?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/115385950975880096/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=115385950975880096' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115385950975880096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115385950975880096'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2006/07/ruby-and-xml.html' title='Ruby and XML'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-115382308498861454</id><published>2006-07-13T03:19:00.000-07:00</published><updated>2006-08-01T13:22:13.803-07:00</updated><title type='text'>Groovy and SOAP</title><content type='html'>All right, i've never seen SOAP implemented as easy as this:&lt;br/&gt;&lt;br/&gt;Write a groovy-Script like that:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class SOAPTest {&lt;br /&gt;&amp;nbsp;&amp;nbsp;String printMe(String name) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return "Hello "+ name&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Start a SOAP-Server:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import groovy.net.soap.SoapServer&lt;br /&gt;def server = new SoapServer("localhost", 6980)&lt;br /&gt;server.setNode("SOAPTest")&lt;br /&gt;server.start()&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And check it with a client:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import groovy.net.soap.SoapClient&lt;br /&gt;def proxy = new SoapClient("http://localhost:6980/SOAPTest?wsdl")&lt;br /&gt;def result = proxy.printMe("Johnny")&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;More Information at the Codehaus-Homepage:&lt;br /&gt;&lt;a href="http://groovy.codehaus.org/Groovy+SOAP"&gt;Groovy and SOAP @ codehaus.org&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-115382308498861454?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/115382308498861454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=115382308498861454' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115382308498861454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/115382308498861454'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2006/07/groovy-and-soap.html' title='Groovy and SOAP'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-113576531829408864</id><published>2006-07-07T02:15:00.000-07:00</published><updated>2006-08-01T13:22:32.923-07:00</updated><title type='text'>Pattern: Good Citizen</title><content type='html'>Every good OO-Developer knews: couple your objects as loose as possible, I already mentioned a popular IOC-Container (PicoContainter, &lt;a href="http://derklammeraffe.blogspot.com/2005/12/picocontainer.html"&gt;article&lt;/a&gt;)&lt;br/&gt;Dan North and Aslak Hellesoy defined the pattern "Good Citizen", you can check it out at the &lt;a href="http://picocontainer.codehaus.org"&gt;PicoContainer-Homepage&lt;/a&gt;. It sets some Rules for "well designed" classes, like the Dependency Injection Pattern which is the basis for all the IOC-Frameworks out there.&lt;br/&gt;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...&lt;br/&gt;&lt;br/&gt;&lt;a href="http://picocontainer.codehaus.org/Good+Citizen"&gt;to the Pattern@codehaus.org&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-113576531829408864?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/113576531829408864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=113576531829408864' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/113576531829408864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/113576531829408864'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2006/07/pattern-good-citizen.html' title='Pattern: Good Citizen'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-113519922821459782</id><published>2005-12-23T13:06:00.000-08:00</published><updated>2006-08-02T05:30:54.773-07:00</updated><title type='text'>Ruby on Rails</title><content type='html'>I have translated this article in english &lt;a href="http://derklammeraffe.blogspot.com/2006/07/ruby-on-rails-first-steps.html"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(this is an older article in german, you can find new articles &lt;a href="http://derklammeraffe.blogspot.com"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ruby on Rails ist ein streng auf MVC basierendes Web-Framework, geschrieben und erweiterbar in und mit Ruby. Es baut sehr stark auf einem Generator-Ansatz auf, die komplette Verzeichnisstruktur und die Vorlagen für Models, Views und Controller können generiert werden. Durch den weitesgehenden Verzicht auf Konfigurationsfiles ist es auch für Menschen mit Abneigungen gegenüber Administrationsübungen (Der Autor schließt sich hier ausdrücklich ein) wunderbar geeignet.&lt;br /&gt;Es entfallen sinnentleerte Mapping-Dateien (Klasse Angebot -&gt; Tabelle Angebot), da Ruby anhand von Namensgleichheit zwischen der R- und O-Welt die Objekte und Attribute auf die Datenbank mappt.&lt;br /&gt;&lt;br /&gt;Um das ganze auch mal anhand eines Beispiels zu testen, hier eine kleine, praktische Anwendung: Eine Todo-Listen-Verwaltung. Hier sollen Todo-Listen nebst einzelnen Todos angelegt, geändert, gelöscht und angesehen werden können.&lt;br /&gt;&lt;br /&gt;Aber kommen wir zuerst zur Technik. Um mit Rails arbeiten zu können brauchen wir zuerst Ruby, das bekommen wir auf der &lt;a href="http://ruby-lang.org"&gt;Ruby-Homepage&lt;/a&gt;. Um eine Datenbankanwendung entwickeln zu können, benötigen wir ausserdem ein Datenbanksystem. Typischerweise verwenden wir hier das (mittlerweile) auch einfach zu bedienende &lt;a href="http://www.mysql.com"&gt;MySQL&lt;/a&gt;, hier im Beispiel in der Version 4.1. Nebst dem kostenlosen MySQL Administrator 1.1. Beides auf der &lt;a href="http://www.mysql.com"&gt;MySQL-Homepage&lt;/a&gt; zu beziehen.&lt;br /&gt;&lt;br /&gt;Nach der Installation können wir in per Kommandozeile mit dem bei Ruby mitgelieferten Package Manager Rails installieren.&lt;br /&gt;&lt;pre&gt;gem install rails --include-dependencies&lt;/pre&gt;&lt;br /&gt;Nun erstellen wir das Projekt "Todo":&lt;br /&gt;&lt;pre&gt;rails todo&lt;/pre&gt;&lt;br /&gt;Dadurch wird der komplette Verzeichnisbaum generiert. In dem Unterverzeichnis "app" landen später die views, models und controller.&lt;br /&gt;&lt;br /&gt;Als nächstes erstellen wir eine neue Datenbank (Schema) unter MySQL mit Namen "todo" inklusive zwei Tabellen:&lt;br /&gt;&lt;pre&gt;lists (id, name, bezeichnung)&lt;br /&gt;todos (id, name, txt, list_id)&lt;/pre&gt;&lt;br /&gt;So, jetzt editieren wir im Verzeichnis todo/config die Datei database.yml und passen sowohl die Entwicklungs-, Produktions- und Testdatenbankeinstellungen entsprechend unserer Umgebung ein.&lt;br /&gt;&lt;br /&gt;Starten wir nun den Web-Server:&lt;br /&gt;&lt;pre&gt;ruby script/server&lt;/pre&gt;&lt;br /&gt;Mit einem Klick auf &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt; bekommen wir den erfolgreichen Start bescheinigt.&lt;br /&gt;&lt;br /&gt;Lassen wir Rails nun seine Stärken ausspielen. Durch die Benennung der Listen-Tabelle in "lists", schließt Rails darauf, dass eine Komponente "List" in unserer Anwendung auf sie mappt. Rails ist hierbei (im Englischen) sehr Clever, mappt auch von "Entries" auf "Entry". Hier erkennen wir zum ersten Mal den von den Entwicklern und dem Autor vertretenen Vorsatz "Konvention über Konfiguration". Zwar ist der Code Konventionen unterlegen, dafür sind Deployment-Deskriptoren und Mapping-Files passe.&lt;br /&gt;&lt;br /&gt;Generieren wir nun model und controller der Komponente "List":&lt;br /&gt;&lt;pre&gt;ruby script\generate model List&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;ruby script\generate controller List&lt;/pre&gt;&lt;br /&gt;Erneut generiert Rails die Stubs für uns, inklusive Helper-Klassen und Unit-Tests.&lt;br /&gt;&lt;br /&gt;Editieren wir nun unter app/controller die Datei list_controller.rb und schreiben innerhalb der Klasse&lt;br /&gt;&lt;pre&gt;scaffold :list&lt;/pre&gt;&lt;br /&gt;Ein Klick auf &lt;a href="http://localhost:3000/list/new"&gt;http://localhost:3000/list/new&lt;/a&gt; zeigt uns, was wirkliches Prototyping ist. Die CRUD (Create, Remove, Update, Destroy) Funktionalität ist komplett vorhanden. Und das mit nur einer Zeile Code im Controller.&lt;br /&gt;&lt;br /&gt;Mehr hierzu demnächst.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://del.icio.us/post" onclick="window.open('http://del.icio.us/post?v=4&amp;noui&amp;jump=close&amp;url=http://derklammeraffe.blogspot.com/2005/12/ruby-on-rails.html&amp;title='+encodeURIComponent(document.title), 'delicious','toolbar=no,width=700,height=400'); return false;"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/983/744/400/delicious_s.0.gif" border="0" alt="" /&gt; add this article to del.icio.us&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-113519922821459782?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/113519922821459782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=113519922821459782' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/113519922821459782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/113519922821459782'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2005/12/ruby-on-rails.html' title='Ruby on Rails'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-113528678682001043</id><published>2005-12-22T13:17:00.000-08:00</published><updated>2005-12-22T13:26:27.816-08:00</updated><title type='text'>News: AJAX-Framework als Apache-Projekt vorgeschlagen</title><content type='html'>Hm, brauchen wir AJAX? Mal überlegen, was war mein erster Gedanke? A steht für Asynchronous. Das ist ok. J für JavaScript. Autsch. JavaScript als Bestandteil eines neuen Hypes? AJ - And XML. Spätestens seit zu großen build-Files diverser Ant-Jünger und zerklüffteten 2.1er EJB-Deployment-Deskriptoren auch lieber nicht.&lt;br /&gt;Da hofft man also, dass der Endandwender sich mit dem Response/Request Zyklus abgefunden hat bis modernere Technologien Abhilfe schaffen, da findet doch einer raus, dass man über ein XMLHTTPRequest-Objekt per JavaScript Abfragen auf den Server machen kann. Jetzt auch bei Apache. &lt;br /&gt;Nun, JSP sorgte dafür, dass man per Tags keinen serverseitigen Skriptcode mehr benötigt, jetzt haben wir wieder den Clientseitigen.&lt;br /&gt;Wems gefällt. Mehr dazu hier:&lt;br /&gt;&lt;a href="http://www.golem.de/0512/42348.html"&gt;artikel@golem.de&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-113528678682001043?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/113528678682001043/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=113528678682001043' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/113528678682001043'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/113528678682001043'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2005/12/news-ajax-framework-als-apache-projekt.html' title='News: AJAX-Framework als Apache-Projekt vorgeschlagen'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-113519890612993594</id><published>2005-12-21T13:00:00.000-08:00</published><updated>2005-12-21T13:01:46.133-08:00</updated><title type='text'>Picocontainer</title><content type='html'>Picocontainer ist ein sogenannter IOC-Container. IOC steht für Inversion of Control und wurde (soweit ich informiert bin) von Martin Fowler vor einiger Zeit auf den Begriff Dependency Injection konkretisiert. Grundsätzlich bedeutet IOC, dass die Kontrolle für die Erstellung von abhängigen Objekten nicht mehr explizit sondern implizit gesteuert wird. &lt;br /&gt;&lt;br /&gt;Beispiel:&lt;br /&gt;public class KundeDAO {&lt;br /&gt;   [..]&lt;br /&gt;   Database db = new OracleDatabaseImpl();&lt;br /&gt;   [..]&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;In dieser Klasse ist die Verknüpfung zur Datenbankimplementierung fest, eine Wiederverwendung der Klasse wäre unter eines Deploys auf einem MSSQLServer problematisch. Falls eine Vielzahl kleiner Objekte viele Beziehungen zueinander aufbauen ist von einer losen Koppelung kaum noch zu sprechen.&lt;br /&gt;&lt;br /&gt;Vereinfachend gehe ich jetzt nur auf zwei Arten von Dependency Injection ein&lt;br /&gt;&lt;br /&gt;Möglichkeit 1:&lt;br /&gt;Setter Injection&lt;br /&gt;&lt;br /&gt;public class KundeDAO {&lt;br /&gt;  [..]&lt;br /&gt;  Database db;&lt;br /&gt;&lt;br /&gt;  public void setDatabase(Database db) {&lt;br /&gt;     this.db = db;&lt;br /&gt;  }&lt;br /&gt;  [..]&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Möglichkeit 2:&lt;br /&gt;Constructor Injection&lt;br /&gt;&lt;br /&gt;public class KundeDAO {&lt;br /&gt;  [..]&lt;br /&gt;  Database db;&lt;br /&gt;&lt;br /&gt;  public KundeDAO(Database db) {&lt;br /&gt;     this.db = db;&lt;br /&gt;  }&lt;br /&gt;  [..]&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Schauen wir uns in erster Linie Möglichkeit 2 an. Die Beziehungen (hier vereinfacht nur die Datenbank) werden übergeben, durch die Abstraktion zum Interface Database kann jede Form von Datenbank übergeben werden. Damit bleiben die Objekte lose gekoppelt und die Wiederverwendbarkeit steigt enorm.&lt;br /&gt;&lt;br /&gt;Mit einem IOC-Container wie Picocontainer entfällt die direkte Verwaltung und Zuordnung der Beziehungen und die platz- und zeitraubende Instanzierung abhängiger Objekte, da der Container die Abhängigkeiten "injiziert" (daher Dependency Injection) und die Klassen selbst nicht mehr für die Erstellung verantwortlich sind.&lt;br /&gt;&lt;br /&gt;Um das auf obiges Beispiel anzuwenden, würde ein Code-Snippet folgendermaßen aussehen:&lt;br /&gt;&lt;br /&gt;MutablePicoContainer pico = new DefaultPicoContainer();&lt;br /&gt;pico.registerComponentImplementation(OracleDatabaseImpl.class);&lt;br /&gt;pico.registerComponentImplementation(KundeDAO.class);&lt;br /&gt;KundeDAO kunde = (KundeDAO) pico.getComponentInstance(KundeDAO.class);&lt;br /&gt;&lt;br /&gt;Hier werden einem neu erstellten PicoContainer die einzusetzenden Klassen übergeben und anschließend eine Instanz der KundeDAO-Klasse erstellt. Per Hand würde man das folgendermaßen abbilden:&lt;br /&gt;&lt;br /&gt;Database database = new OracleDatabaseImpl();&lt;br /&gt;KundeDAO kunde = new KundeDAO(database);&lt;br /&gt;&lt;br /&gt;Bei einem so trivialen Beispiel wie hier macht das eher wenig Sinn. Wenn allerdings viele Klassen viele Abhängigkeiten untereinander haben ermöglicht Pico eine weniger starre Kopplung.&lt;br /&gt;&lt;br /&gt;Soviel zur Einführung. Pico bietet auch Lifecycle-Support an und wirkt sehr sauber entwickelt (Test-First). Mehr Infos gibt es hier:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.picocontainer.org/"&gt;Picocontainer Homepage&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.picocontainer.org/Five+minute+introduction"&gt;Pico 5-Minuten Einführung&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-113519890612993594?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/113519890612993594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=113519890612993594' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/113519890612993594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/113519890612993594'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2005/12/picocontainer.html' title='Picocontainer'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20076456.post-113519877922524322</id><published>2005-12-21T12:58:00.000-08:00</published><updated>2005-12-21T12:59:39.240-08:00</updated><title type='text'>CSS - Einführung Teil 1</title><content type='html'>Wer schon einmal eine Homepage erstellt hat, kennt das Problem: Der Code wird spätestens bei den Designanpassungen (Schriften, Hintergrundbilder,...) unübersichtlich und vor allem schwer wartbar. Das kommt daher, weil das "Was?" (Was wird angezeigt?) und das "Wie?" (Wie wird es angezeigt?) im HTML vermischt vorliegen.&lt;br /&gt;Die Lösung aus der Misere: Cascading Style Sheets, von Freunden "CSS" genannt.&lt;br /&gt;&lt;br /&gt;Ein Beispiel. Nachfolgend eine Demonstrationsseite (das unter CSS-Jüngern alseits bekannte "CSS Zen Garden Projekt") in reinem HTML.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.csszengarden.com/zengarden-sample.html"&gt;Demo-Seite&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hier ist lediglich das "Was?" hinterlegt. Da CSS extern das "Wie?" übernehmen kann, können mit zwei unterschiedlichen CSS-Dateien ein und die selbe HTML auf vollkommen unterschiedlichen Wegen interpretiert werden.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.csszengarden.com/?cssfile=/190/190.css&amp;page=0"&gt;Beispiel 1&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.csszengarden.com/?cssfile=/187/187.css&amp;page=0"&gt;Beispiel 2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Diese Beispiele haben beide ein und dieselbe HTML-Datei, die Texte sind identisch, aber durch CSS wird da Layout vollkommen anders dargestellt.&lt;br /&gt;&lt;br /&gt;Ein erster Schritt:&lt;br /&gt;&lt;br /&gt;Nehmen wir einmal folgenden HTMLcode zur Grundlage:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; &amp;lt;html&amp;gt;&lt;br /&gt;  &amp;lt;head&amp;gt;&lt;br /&gt;  &amp;lt;/head&amp;gt;&lt;br /&gt;  &amp;lt;body&amp;gt;&lt;br /&gt;    &amp;lt;h3&amp;gt;Ein erster Test&amp;lt;/h3&amp;gt;&lt;br /&gt;    Mit ein kleinwenig Text&lt;br /&gt;  &amp;lt;/body&amp;gt;&lt;br /&gt; &amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Zeigt man diesen Code im Browser an, wird einfach eine Überschrift mit etwas Text abgebildet:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Ein erster Test&lt;/h3&gt;&lt;br /&gt;Mit ein kleinwenig Text&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Langweilig, oder? Passen wir doch ein wenig die Schrift an. Wir schreiben eine Datei test.css:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  body {&lt;br /&gt;    font: normal 10px/1.6em "Lucida Grande", "Verdana", sans-serif;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  h3 {&lt;br /&gt;    color: red;&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Dem aufmerksamen Betrachter fällt auf, dass vor den {}-Klammern jeweils ein HTML-Tag steht. In den Klammern werden dann Anpassungen für diesen Tag implementiert. Wenn wir also wollen, dass sämtliche h3-Überschriften auf unserer Website rot sind, müssen wir lediglich das obenstehende css-File einbinden.&lt;br /&gt;Hierfür müssen wir im &amp;lt;head&amp;gt;-Abschnitt folgenden Code hinzufügen:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  &amp;lt;link rel="stylesheet" type="text/css" href="test.css" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Das Ergebnis mit CSS:&lt;br /&gt;&lt;a href="http://www.cloutier.de/blog/css/test.html"&gt;hier klicken&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Demnächst mehr!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20076456-113519877922524322?l=derklammeraffe.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://derklammeraffe.blogspot.com/feeds/113519877922524322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20076456&amp;postID=113519877922524322' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/113519877922524322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20076456/posts/default/113519877922524322'/><link rel='alternate' type='text/html' href='http://derklammeraffe.blogspot.com/2005/12/css-einfhrung-teil-1.html' title='CSS - Einführung Teil 1'/><author><name>dan</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='30' src='http://www.cloutier.de/blog/Dharma_wheel_1.png'/></author><thr:total>0</thr:total></entry></feed>
