<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/">

  <channel rdf:about="http://simplericity.com/">
    <title>simplericity</title>
    <link>http://simplericity.com/</link>
    <description>Reducing software entropy</description>
    <items>
      <rdf:Seq>
        
        <rdf:li resource="http://simplericity.com/2008/08/16/1218895920000.html" />
        
        <rdf:li resource="http://simplericity.com/2008/07/24/1216920300000.html" />
        
        <rdf:li resource="http://simplericity.com/2008/04/07/1207589520000.html" />
        
      </rdf:Seq>
    </items>
  </channel>

  
  <item rdf:about="http://simplericity.com/2008/08/16/1218895920000.html">
    <title>Exploring the Glassfish commit history with SVNSearch</title>
    <link>http://simplericity.com/2008/08/16/1218895920000.html</link>
    
      
        <description>
          &lt;br /&gt;
I recently added the &lt;a href=&#034;https://glassfish.dev.java.net/&#034;&gt;Glassfish&lt;/a&gt; Subversion repository to &lt;a href=&#034;http://svnsearch.org/&#034;&gt;SVNSearch.org&lt;/a&gt;. &lt;a href=&#034;http://blogs.sun.com/psterk/&#034;&gt;Paul Sterk&lt;/a&gt;, the community manager for Glassfish, asked if I could provide some background on SVNSearch.org and the benefits of having Glassfish indexed there. So, here are some ways to use SVNSearch:&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Who changed what, when?&lt;/h2&gt;
SVNSearch helps you keep track of, understand and learn from changes in version control systems. The basic interface shows you the most recent commits. Here&#039;s a screenshot from the Glassfish project:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&#034;http://svnsearch.org/svnsearch/repos/GLASSFISH/search&#034;&gt;&lt;img src=&#034;http://simplericity.com/images/glassfish/search.png&#034; alt=&#034;&#034; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
But SVNSearch can do better than that. You can limit your search by log message, path, file name, file type, date, author or a referenced issue number. The following screenshot shows all commits done by &lt;a href=&#034;http://weblogs.java.net/blog/kohsuke/&#034;&gt;kohsuke&lt;/a&gt; last year in the /gfsvn directory having the word &amp;quot;fixed&amp;quot; in the log message:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&#034;http://svnsearch.org/svnsearch/repos/GLASSFISH/search?logMessage=fixed%20bug&amp;amp;path=%2Fgfsvn&amp;amp;author=kohsuke&#034;&gt;&lt;img alt=&#034;&#034; src=&#034;http://simplericity.com/images/glassfish/fixed_kohsuke.png&#034; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
You might have noticed the charts on the left side of the screen. These statistics show commit distribution by path, time and&amp;nbsp; author and they are generated for each search you make.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;What changes were made to file X in revision Y?&lt;/h2&gt;
Once you&#039;ve find the commit you&#039;re looking for you might be interested in see what changes were actually  made in the files affected by the commit. By clicking on the a path SVNSearch shows you a side-by-side colored diff of the change, including inline changes:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&#034;http://svnsearch.org/svnsearch/repos/GLASSFISH/search?p=/trunk/v3/distributions-prelude/distributions.xml&amp;amp;rev=21955&amp;amp;&#034;&gt;&lt;img alt=&#034;&#034; src=&#034;http://simplericity.com/images/glassfish/diff.png&#034; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Which developers work on the same part of the project?&lt;/h2&gt;
For each file in the repository, SVNSearch knows who made any change to that file. It also knows who else have touched that file and uses this information to provide a reasonably sophisticated collaboration graph. This graph will have one node for each developer in the project and there will be an edge between any two developers that have worked on the same code. Developers tend to be placed near closely if they&#039;ve worked on lots of common files.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&#034;http://svnsearch.org/svnsearch/repos/GLASSFISH/search?view=graph&#034;&gt;&lt;img src=&#034;http://simplericity.com/images/glassfish/collaboration.png&#034; alt=&#034;&#034; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Developers who have committed recently are red while people who haven&#039;t committed in a while gets a more blue color. The Glassfish shows a group of developers in the upper left part of the graph, so let&#039;s zoom in on them and show their names:&lt;br /&gt;
&lt;br /&gt;
&lt;img src=&#034;http://simplericity.com/images/glassfish/collaboration-zoomed.png&#034; alt=&#034;&#034; /&gt;&lt;br /&gt;
&lt;br /&gt;
The collaboration graph can be also useful for identifying parts of the code base that have been abandoned or for learning about the knowledge flow in the project. Sometimes two groups of developers are connected by a single developer, that means this developer is probably important for the flow of knowledge in the project since he&#039;s the only one who&#039;s worked on both parts of the code base. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;When do people commit?&lt;/h2&gt;
Say you want to get an overview of who is or has been involved in a project. You don&#039;t care about the details what actually changed so a detailed change list doesn&#039;t actually help you. For these cases, SVNSearch provides a timeline plot of all changes in the project, grouped by author.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&#034;http://svnsearch.org/svnsearch/repos/GLASSFISH/search?view=plot&amp;amp;plotsort=commits&#034;&gt;&lt;img alt=&#034;&#034; src=&#034;http://simplericity.com/images/glassfish/timeline.png&#034; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Every red dot in this plot is a commit. The X axis is the timeline of the project and the Y axis actually show time of day of the commit. The list of authors can be ordered by name, first commit, last commit, total lifespan or number of commits which is the ordering used in the above example from Glassfish.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Developer turnover&lt;/h2&gt;
Long lived software projects always experience a certain degree of developer turnover. People leave the project and new developers join. SVNSearch includes a developer turnover chart that is based on &lt;a href=&#034;http://libresoft.es/downloads/developer-turnover-14pages.pdf&#034;&gt;the work of Gregorio Robles and Jesus M. Gonzalez-Barahona&lt;/a&gt; of Universidad Rey Juan Carlos, Spain.&lt;br /&gt;
&lt;br /&gt;
The idea is to track the 20% most active active developers in each one of ten intervals of the total timeline of the project and then track how active these developers are in the rest of the time intervals of the project.&lt;br /&gt;
&lt;br /&gt;
While the theory is interesting, you don&#039;t really have to understand it all to make use of it. A rule of thumb is that many horizontal lines indicates a stable core group, while diagonal lines signals that the core group is being replaced.&lt;br /&gt;
&lt;br /&gt;
The Glassfish project has a quite stable core group according to SVNSearch:&lt;br /&gt;
&lt;br /&gt;
&lt;img alt=&#034;&#034; src=&#034;http://simplericity.com/images/glassfish/turnover.png&#034; /&gt;&lt;br /&gt;
&lt;h2&gt;&amp;quot;Let me know when it&#039;s committed&amp;quot;&lt;/h2&gt;
Dependencies is something we have a lot of, not only in our software but also in software development. Have you ever had to wait for someone else to make a change in &amp;quot;their&amp;quot; code before you can continue with &amp;quot;your&amp;quot; coding? &lt;br /&gt;
&lt;br /&gt;
Any search in SVNSearch has an RSS feed, so if you&#039;re waiting for a specific change, why not just search for that and then subscribe to the feed? Here&#039;s an example show recent changes in Glasshfish using the RSS Screen Saver in OS X:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&#034;http://svnsearch.org/svnsearch/repos/GLASSFISH/search?rss&#034;&gt;&lt;img alt=&#034;&#034; src=&#034;http://simplericity.com/images/glassfish/notifications.png&#034; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Background and future of the SVNSearch project&lt;br /&gt;
&lt;/h2&gt;
I started working on SVNSearch about four years back. The company I worked for at the time used CVS and suggested we started using Subversion instead. There tool support for Subversion wasn&#039;t all that good at the time but I was able to find alternatives for most of our tool chain. The CVS tool that I couldn&#039;t find a replacement for was the query interface in ViewCVS. So that&#039;s how I started working on SVNSearch.&lt;br /&gt;
&lt;br /&gt;
Over the years I&#039;ve added the features you&#039;ve seen here and more,&amp;nbsp; but I&#039;ve spent most of the time making sure SVNSearch is really, really fast and making it scale to millions of revisions. SVNSearch.org today indexes over 3.3 million revisions with the largest repository being &lt;a href=&#034;http://svnsearch.org/svnsearch/repos/KDE/search&#034;&gt;KDE&lt;/a&gt; with over 840.000 commits alone.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&#034;http://svnsearch.org&#034;&gt;SVNSearch.org&lt;/a&gt; is a free service I provide to the open source community. My plan is to offer SVNSearch as a product on a commercial basis and I have a few customers in a private beta round now. I can&#039;t promise any public release date yet, but if you&#039;re interested in joining the beta, let me know.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve recently added enterprise features such as LDAP integration, Kerberos / Active Directory Single Sign-On, and role based security. But those features are more interesting when using SVNSearch inside a company firewall and probably not that interesting for an open source project like Glassfish :-)&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
&lt;h2&gt;Oh, just one more thing: I &lt;em&gt;always&lt;/em&gt; enjoy feedback!&lt;br /&gt;
&lt;/h2&gt;
&lt;br /&gt;
Whether you like SVNSearch or not, I&#039;d love to hear your thoughts. Perhaps you&#039;ve found a bug, have an idea for a new feature or just want to let me know you&#039;re using it. In any case don&#039;t hesitate to use the &lt;a href=&#034;http://svnsearch.org/svnsearch/sendfeedback&#034;&gt;feedback form&lt;/a&gt; on SVNSearch.org or just send me an email. (feedback at svnsearch dot com)
        </description>
      
      
    
  </item>
  
  <item rdf:about="http://simplericity.com/2008/07/24/1216920300000.html">
    <title>Yes, cross-platform Single Sign-On for Java Webapps is possible.</title>
    <link>http://simplericity.com/2008/07/24/1216920300000.html</link>
    
      
        <description>
          A customer participating in the &lt;a href=&#034;http://svnsearch.org&#034;&gt;SVNSearch&lt;/a&gt; beta round asked me about Single Sign-On solutions for SVNSearch. SSO has become something of holy grail in the Enterprise. Everyone wants it but few seem to really achieve it. The Wikipedia article for &lt;a href=&#034;javascript:void(0);/*1216920824305*/&#034;&gt;Single Single-On&lt;/a&gt; even cites a Gartner report stating that &amp;quot;no one can achieve it without a homogeneous IT infrastructure&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
What could be a better motivation than Gartner saying it&#039;s impossible? I decided I&#039;d prove them wrong and took on the task to create a cross platform, Single Sign-On solution for SVNSearch.&lt;br /&gt;
&lt;br /&gt;
&lt;img alt=&#034;&#034; src=&#034;http://simplericity.com/images/sso/looking.jpg&#034; /&gt;&lt;br /&gt;
&lt;h2&gt;The NTLM headache&lt;/h2&gt;
As it turns out, there are only a couple of options available for Web SSO . The Java CIFS Client Library (&lt;a href=&#034;javascript:void(0);/*1216920861940*/&#034;&gt;JCIFS&lt;/a&gt;) implements Microsoft&#039;s NTLM technology. NTLM is a challenge-response authentication mechanism, and being a product of Microsoft it&#039;s not much of a surprise that it has a history of security weaknesses.&lt;br /&gt;
&lt;br /&gt;
NTLM has caused me lots of headache on a past project because it doesn&#039;t play nice with the basic rules of HTTP. NTLM is a connection-oriented protocol, so both the server and the client needs to keep the same TCP connection open for at least the three request it takes to do the authentication. This is just fine when Internet Explorer is talking to Microsoft&#039;s IIS server, but when you introduce a web server like Tomcat, weird things start happening.&amp;nbsp; In our case Tomcat would start sending Connection: close headers under heavy load. This is a perfectly sensible thing to do &amp;ndash; if you&#039;re running low on available threads, turing off keep-alive is&amp;nbsp; better than refusing requests. But in the NTLM case it made Internet Explorer fail with a non-decipherable error page. &lt;br /&gt;
&lt;br /&gt;
Finally, NTLM isn&#039;t really cross platform. Both Firefox and Safari have adopted NTLM, but they&#039;ll pop up a username/password dialog on non Windows platforms. &lt;br /&gt;
&lt;h2&gt;Enter Kerberos&lt;/h2&gt;
So you might not be surprised to hear I wanted something better than NTLM. I&#039;d been reading about Kerberos for years, but my impression was that it required an army of sysadmins to set up and a Ph.D in cryptography to create software for it.&amp;nbsp; Then I realized Microsoft actually use Kerberos for their domain controllers so I already had the infrastructure set up. I started looking for open source projects implementing Kerberos authentication, but I couldn&#039;t really find anything. There were a lot of pointers to a an &lt;a href=&#034;javascript:void(0);/*1216920959962*/&#034;&gt;old patch&lt;/a&gt; providing Kerberos support for JCIFS, but it doesn&#039;t seem like it ever got applied.&lt;br /&gt;
&lt;br /&gt;
So it seemed like I had no option but to roll my own. In doing so, I had to spend some time trying to understand how Kerberos works. And it&#039;s not really that hard. Every time you log on to your Windows Domain Controller, Windows acquires a Kerberos token from the Domain Controller. This token can be used to fetch another type of token that lets you log into network services like my Java based web server. The service also has to authenticate itself and that is taken care of by issuing KeyTab files containing secret keys for the service.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;The implementation&lt;/h2&gt;
Kerberos is implemented in Java through the GSS API. GSS is a just a wrapper API around token based security mechanisms like Kerberos and doesn&#039;t provide any security itself. The authentication of the service is done through a JAAS LoginModule, the &lt;a href=&#034;javascript:void(0);/*1216921004740*/&#034;&gt;Krb5LoginModule&lt;/a&gt;.&amp;nbsp; The module needs to be configured to use a KeyTab file and to store the credentials in the Subject. This way the credentials can be used in the next step when authenticating users. You only need to do the service login once, after that you can keep the Subject around as long as the service is running.&lt;br /&gt;
&lt;br /&gt;
It&#039;s important to name the service principal correctly. The principal name needs to match the host name of the service&amp;nbsp; and the host name needs to have a DNS A record who&#039;s IP address resolves back to the host name. User authentication is done through the GSSAPI. I&#039;m using the GSSManager to create a &lt;a href=&#034;javascript:void(0);/*1216921049497*/&#034;&gt;GSSContext&lt;/a&gt;. This context is then fed the Kerberos token in the acceptSecContext() method and&amp;nbsp; if isEstablished() returns true we can fetch the identity of the authenticated user with getSrcName().&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Web-based Kerberos&lt;/h2&gt;
Kerberos was invented before the web and doesn&#039;t specify how tokens should be transported in a web context. Microsoft implemented SPNEGO in Internet Explorer 5.01 as an HTTP authentication mechanism. When the server requires user authentication it sends a HTTP 401 status back to the user with a &amp;laquo;WWW-Authenticate: Negotiate&amp;raquo; header. The browser then resubmits the request, now with a &amp;laquo;Authorization&amp;raquo; header containing a security token. This ping-pong game continues until the underlying security mechanism is negotiated and the user is authenticated. SPNEGO is a pseudo mechanism used to negotiate the use of a real mechanism in the case that the server and client don&#039;t agree on a mechanism upfront. SPNEGO is implemented in Java 1.6 as a part of the Java GSS API. However, the SPNEGO token is DER encoded so it&#039;s pretty straight forward to extract the real&amp;nbsp; Kerberos token from a SPNEGO token if you&#039;re running on Java 5 or 1.4.&lt;br /&gt;
&lt;br /&gt;
&lt;img src=&#034;http://simplericity.com/images/sso/tind.jpg&#034; alt=&#034;&#034; /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Cross-platform support&lt;/h2&gt;
OS X supports Kerberos. You can set up OS X to acquire Kerberos tickets when logging in or you can use kinit command line tool or the graphical utility Kerberos.app for&amp;nbsp; ticket administration. Most Linux distributions also have Kerberos support. Kerberos is supported in&amp;nbsp; both Safari and Firefox, although Firefox doesn&#039;t send SPNEGO tokens but pure Kerberos tokens instead. So my code needed to take that into account. &lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;The result&lt;/h2&gt;
Although it did require a fair amount of research and development I must say I&#039;m very happy with the end result. I now have a 100% pure Java Single Sing-On toolkit. Having complete control of the authentication process also gives some nice extras. I can present the user with a fallback login page if automatic login fails. I can also let the administrator test the Kerberos configuration and provide some useful feedback if something doesn&#039;t work. &lt;br /&gt;
&lt;br /&gt;
If there&#039;s any interest in this&amp;nbsp; code please let me know. I might consider making a small open source project out of it or contribute it to an&amp;nbsp; existing project. And to the Gartner dudes: I now have Kerberos based SSO solution that works great in a cross-platform environment,&amp;nbsp; so go eat your socks!&lt;br /&gt;
&lt;br /&gt;
&lt;img src=&#034;http://simplericity.com/images/sso/kerbconf.jpg&#034; alt=&#034;&#034; /&gt;
        </description>
      
      
    
  </item>
  
  <item rdf:about="http://simplericity.com/2008/04/07/1207589520000.html">
    <title>Implementing decorator templates with Apache Velocity</title>
    <link>http://simplericity.com/2008/04/07/1207589520000.html</link>
    
      
        <description>
          A couple of years ago I started replacing JSPs with &lt;a href=&#034;http://velocity.apache.org&#034;&gt;Apache Velocity&lt;/a&gt; for generating&amp;nbsp; HTML in my web applications. The simplicity and speed of Velocity was very appealing to me compared to the complex beast that JSP is. &lt;br /&gt;
&lt;br /&gt;
Compiling JSP to Java, then to byte code and then loading and running it as class obviously must have seemed like a good idea to those who came up with it. For me, it&#039;s always been crazy talk.&lt;br /&gt;
&lt;br /&gt;
When designing HTML templates reusability is always an important goal. You want to define your header, menu and footer once and then reuse them for both your front page, article page or about page.&lt;br /&gt;
&lt;br /&gt;
The no-brainer solution to this is to use tags or directives to include common snippets of HTML into the final page. JSP supports this with the @include syntax&amp;nbsp; or the &amp;lt;jsp:include/&amp;gt; tag:&lt;br /&gt;
&lt;br /&gt;
&lt;img src=&#034;http://simplericity.com/images/velocitydecorators/jsp-include.png&#034; alt=&#034;&#034; /&gt;&lt;br /&gt;
&lt;br /&gt;
Like any no-brainer solution this one is not very smart. You end up with brittle and inflexible templates where you need to touch all your templates to do any kind of structural changes to your main design.&lt;br /&gt;
&lt;br /&gt;
A much better solution is to apply the decorator pattern. Instead of pulling in common pieces of HTML everywhere you need them you just specify what&#039;s special with this particular page and then apply a decorator template to it. This template will take care of creating the actual design.&lt;br /&gt;
&lt;br /&gt;
There&#039;s no built in support for creating decorator templates in JSP, so what used to do was to create a small taglib that would let me define a snippet of HTML as a section and then output that snippet in the design template. I know a lot of people use Sitemesh for this, but I found the taglib solution worked very well for my purpose.&lt;br /&gt;
&lt;br /&gt;
&lt;img src=&#034;http://simplericity.com/images/velocitydecorators/jsp-taglib.png&#034; alt=&#034;&#034; /&gt;&lt;br /&gt;
&lt;br /&gt;
Like JSP, Velocity has no built in support for creating decorator templates. At first I just accepted this situation as a trade-off. With Velocity being so simple, I&#039;d just have to learn to live with all the #incude directives right?&lt;br /&gt;
&lt;br /&gt;
That was until I discovered that Velocity actually has support for custom directives. So now all I had to do was to create a directive that rendered it&#039;s body into a string and stored that in the context for later use. This turned out to be very easy:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&#034;java&#034; name=&#034;code&#034;&gt;public class Section extends Directive {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; public String getName() {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &amp;quot;section&amp;quot;;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; public int getType() {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return BLOCK;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ASTReference nameNode = (ASTReference) node.jjtGetChild(0);&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String name = nameNode.getRootString();&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; StringWriter sw = new StringWriter();&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; node.jjtGetChild(1).render(context, sw);&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.put(name, sw.toString());&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return true;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt; }  &lt;/pre&gt;
&lt;br /&gt;
Now I can create templates like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&#034;html&#034; name=&#034;code&#034;&gt;#section($content)&lt;br /&gt;&amp;lt;h1&amp;gt;Content here&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;Hello World&amp;lt;/p&amp;gt;&lt;br /&gt;#end&lt;br /&gt;&lt;br /&gt;#parse(&amp;quot;design.vm&amp;quot;) &amp;nbsp;&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
Registering my #section directive with Velocity was easy. Adding a &lt;code&gt;userDirective&lt;/code&gt; property with the name of the directive class did the trick.&lt;br /&gt;
&lt;br /&gt;
Seeing how easy this is and how much better it made my template system I&#039;m amazed that Velocity doesn&#039;t already have something like this in its core.
        </description>
      
      
    
  </item>
  

</rdf:RDF>
