<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.3.3" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Celerity ICT</title>
	<link>http://www.celerity.nl</link>
	<description></description>
	<pubDate>Mon, 21 Dec 2009 16:35:28 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.3</generator>
	<language>en</language>
			<item>
		<title>The jQuery fromTemplate plugin</title>
		<link>http://www.celerity.nl/blog/2009/12/jquery-fromtemplate-plugin/</link>
		<comments>http://www.celerity.nl/blog/2009/12/jquery-fromtemplate-plugin/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 10:43:19 +0000</pubDate>
		<dc:creator>Tomas Salfischberger</dc:creator>
		
		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.celerity.nl/blog/2009/12/jquery-fromtemplate-plugin/</guid>
		<description><![CDATA[We started using the Micro-Templating concept by John Resig to separate HTML markup from Javascript code in JSON based applications like our online crm solution. This concept solves the problem of outputting ugly strings of HTML very nicely, but the original code snippit was a little hard to understand for those of us who are [...]]]></description>
			<content:encoded><![CDATA[<p>We started using the <a href="http://ejohn.org/blog/javascript-micro-templating/" target="_blank">Micro-Templating concept</a> by John Resig to separate HTML markup from Javascript code in JSON based applications like our <a href="http://www.celerity-crm.nl">online crm</a> solution. This concept solves the problem of outputting ugly strings of HTML very nicely, but the original code snippit was a little hard to understand for those of us who are not <a href="http://jsninja.com/" target="_blank">Javascript Ninjas</a> (a book by John Resig). To fix this I had created a simple jQuery plugin and refactored the code a little.</p>
<p>This resulted in the following easy to use plugin:</p>
<pre>$("#someElement").fromTemplate("templateId", dataset)</pre>
<p>Where templateId is the ID of the template element and dataset is a simple Javascript object with data to expose to the template. Because this might help others understand the Micro-Templating code a bit better and might be useful to other jQuery users I have just uploaded the code to github as <a href="http://github.com/celerity/jQuery-fromTemplate-plugin" target="_blank">jQuery-fromTemplate-plugin</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.celerity.nl/blog/2009/12/jquery-fromtemplate-plugin/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Update Celerity CRM site</title>
		<link>http://www.celerity.nl/blog/2009/05/update-celerity-crm-site/</link>
		<comments>http://www.celerity.nl/blog/2009/05/update-celerity-crm-site/#comments</comments>
		<pubDate>Sun, 17 May 2009 21:17:34 +0000</pubDate>
		<dc:creator>Koen Bos</dc:creator>
		
		<category><![CDATA[Nieuws]]></category>

		<guid isPermaLink="false">http://www.celerity.nl/blog/2009/05/update-celerity-crm-site/</guid>
		<description><![CDATA[Nadat we de vorige versie van de site hadden geëvalueerd kwamen we tot de conclusie dat deze op verschillende punten nog kon worden verbeterd. Daarom hebben we vanaf vandaag een nieuwe versie van de site gelanceerd. Op de site meer informatie over de functionaliteit, betere demo afhandeling en de mogelijkheid om direct een offerte aan [...]]]></description>
			<content:encoded><![CDATA[<p>Nadat we de vorige versie van de site hadden geëvalueerd kwamen we tot de conclusie dat deze op verschillende punten nog kon worden verbeterd. Daarom hebben we vanaf vandaag een <a href="http://www.celerity-crm.nl" title="Celerity CRM">nieuwe versie van de site</a> gelanceerd. Op de site meer informatie over de functionaliteit, betere demo afhandeling en de mogelijkheid om direct een offerte aan te vragen.</p>
<p>Naast deze aanpassingen zal er in de toekomst nog gekeken worden naar een automatische demo aanvraag en een nieuws onderdeel op de site.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.celerity.nl/blog/2009/05/update-celerity-crm-site/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Nieuwe website Celerity CRM</title>
		<link>http://www.celerity.nl/blog/2009/01/nieuwe-website-celerity-crm/</link>
		<comments>http://www.celerity.nl/blog/2009/01/nieuwe-website-celerity-crm/#comments</comments>
		<pubDate>Wed, 28 Jan 2009 16:20:53 +0000</pubDate>
		<dc:creator>Koen Bos</dc:creator>
		
		<category><![CDATA[Nieuws]]></category>

		<guid isPermaLink="false">http://www.celerity.nl/blog/2009/01/nieuwe-website-celerity-crm/</guid>
		<description><![CDATA[Voor de nieuwe release van Celerity CRM hebben we ook een nieuwe website gebouwd, u vindt de productinformatie vanaf nu op: www.celerity-crm.nl. Uiteraard is het daar ook mogelijk om een demo aan te vragen of een prijsindicatie voor uw organisatie te berekenen.
]]></description>
			<content:encoded><![CDATA[<p>Voor de nieuwe release van <a href="http://www.celerity-crm.nl/">Celerity CRM</a> hebben we ook een nieuwe website gebouwd, u vindt de productinformatie vanaf nu op: <a href="http://www.celerity-crm.nl/">www.celerity-crm.nl</a>. Uiteraard is het daar ook mogelijk om een <a href="http://www.celerity-crm.nl/demo">demo</a> aan te vragen of een <a href="http://www.celerity-crm.nl/prijzen">prijsindicatie</a> voor uw organisatie te berekenen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.celerity.nl/blog/2009/01/nieuwe-website-celerity-crm/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hibernate and invalid queries from empty lists</title>
		<link>http://www.celerity.nl/blog/2009/01/hibernate-creating-invalid-quries-from-empty-lists/</link>
		<comments>http://www.celerity.nl/blog/2009/01/hibernate-creating-invalid-quries-from-empty-lists/#comments</comments>
		<pubDate>Wed, 07 Jan 2009 13:30:58 +0000</pubDate>
		<dc:creator>Tomas Salfischberger</dc:creator>
		
		<category><![CDATA[Hibernate]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.celerity.nl/blog/2009/01/hibernate-creating-invalid-quries-from-empty-lists/</guid>
		<description><![CDATA[Just to keep others from searching for a &#8220;proper&#8221; way to handle this case: I just found out that Hibernate generates invalid SQL (at least in MySQL) when you pass an empty (not null) list to Restrictions.in(). The error occured in a simple query that tried to lookup a list of records by id. The [...]]]></description>
			<content:encoded><![CDATA[<p>Just to keep others from searching for a &#8220;proper&#8221; way to handle this case: I just found out that Hibernate generates invalid SQL (at least in MySQL) when you pass an empty (not null) list to Restrictions.in(). The error occured in a simple query that tried to lookup a list of records by id. The code was something like this:</p>
<pre>public List&lt;Thing&gt; findRecordsByIds(final List&lt;Integer&gt; ids) {
	return (List&lt;Thing&gt;) getHibernateTemplate().execute(new HibernateCallback() {
		public Object doInHibernate(Session session) throws HibernateException, SQLException {
			return session.createCriteria(Thing.class).add(Restrictions.in("thingId", ids));
		}
	});
}</pre>
<p>And it failed with a SQLGrammarException (which should never occur when using the Hibernate Query API). The Hibernate project knows about this as seen in their <a href="http://opensource.atlassian.com/projects/hibernate/browse/HHH-2776">JIRA</a>, but a fix is not yet delivered. Of course an easy fix to my example is:</p>
<pre>public List&lt;Thing&gt; findRecordsByIds(final List&lt;Integer&gt; ids) {
	if(ids.size() == 0) return Collections.emptyList();
	return (List&lt;Thing&gt;) getHibernateTemplate().execute(new HibernateCallback() {
		public Object doInHibernate(Session session) throws HibernateException, SQLException {
			return session.createCriteria(Thing.class).add(Restrictions.in("thingId", ids));
		}
	});
}</pre>
<p>Which also uses another function everybody should know about: Collections.emptyList() which in contrary to Collections.EMPTY_LIST uses a simple form of type inference to create a List&lt;Thing&gt; instead of a raw List and avoids a compiler warning.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.celerity.nl/blog/2009/01/hibernate-creating-invalid-quries-from-empty-lists/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Eclipse crash in CompilerThread on 64-bits Java</title>
		<link>http://www.celerity.nl/blog/2008/11/eclipse-crash-in-compilerthread-on-64-bits-java/</link>
		<comments>http://www.celerity.nl/blog/2008/11/eclipse-crash-in-compilerthread-on-64-bits-java/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 08:36:13 +0000</pubDate>
		<dc:creator>Tomas Salfischberger</dc:creator>
		
		<category><![CDATA[Eclipse]]></category>

		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.celerity.nl/blog/2008/11/eclipse-crash-in-compilerthread-on-64-bits-java/</guid>
		<description><![CDATA[The title describes it all, there is a bug in the Sun JVM version 1.6 update 5 and later versions that makes the CompilerThread in Eclipse crash on 64-bits systems. Bugreports have been filed for Eclipse and the JVM, but the problem is still not resolved with the recent 1.6 update 10 release.
To save anyone [...]]]></description>
			<content:encoded><![CDATA[<p>The title describes it all, there is a bug in the Sun JVM version 1.6 update 5 and later versions that makes the CompilerThread in Eclipse crash on 64-bits systems. Bugreports have been filed for <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=214092">Eclipse</a> and the <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6614100">JVM</a>, but the problem is still not resolved with the recent 1.6 update 10 release.</p>
<p>To save anyone with the same problem a lot of time, a workaround is to add the following line to eclipse.ini:</p>
<pre>-XX:CompileCommand=exclude,org/eclipse/core/internal/dtree/DataTreeNode,forwardDeltaWith</pre>
<p>That stops Java Hotspot&#8217;s JIT compiler from compiling the problem-method and avoids the crash.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.celerity.nl/blog/2008/11/eclipse-crash-in-compilerthread-on-64-bits-java/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Fun with initialization blocks</title>
		<link>http://www.celerity.nl/blog/2008/11/fun-with-initialization-blocks/</link>
		<comments>http://www.celerity.nl/blog/2008/11/fun-with-initialization-blocks/#comments</comments>
		<pubDate>Wed, 05 Nov 2008 09:20:34 +0000</pubDate>
		<dc:creator>Arthur Vlug</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Technology]]></category>

		<category><![CDATA[init initialization block Java constructor]]></category>

		<guid isPermaLink="false">http://www.celerity.nl/blog/2008/11/fun-with-initialization-blocks/</guid>
		<description><![CDATA[After Tomas posted the article Creating a Map in “Ruby-style” in Java, I wanted to tell you a little more about the {  } block notation, which is used in that article to create a HashMap object. It looked like this:

new HashMap() {{
	put("name", "Tomas Salfischberger");
	put("phone", "123456789");
	put("room", "11b");
}};
The { } notation is called an &#8220;initialization [...]]]></description>
			<content:encoded><![CDATA[<p>After Tomas posted the article <a href="http://www.celerity.nl/blog/2008/11/creating-a-map-in-ruby-style-in-java/" title="Creating a Map in “Ruby-style” in Java">Creating a Map in “Ruby-style” in Java</a>, I wanted to tell you a little more about the {  } block notation, which is used in that article to create a HashMap object. It looked like this:</p>
<pre>
new HashMap() {{
	put("name", "Tomas Salfischberger");
	put("phone", "123456789");
	put("room", "11b");
}};</pre>
<p>The { } notation is called an &#8220;initialization block&#8221;. We can also see this notation in action in the following class:</p>
<pre>public class Person {
	protected int age;

	// Initialization block
	{
		age = 30;
	}
	public Person() {
		age = 40;
	}
}</pre>
<p>And you can feel it coming, the bonus-question here is: After creating a Person object, what is the value of the age field? You can try for yourself, or I can just tell you it will be 40. From that we can conclude that the init-block is executed before the constructor. If you check the documentation from Sun, you&#8217;ll find that init-blocks are indeed prepended to every constructor.</p>
<p>A new question arises: How could Tomas have used the put method in an init-block before the constructor of the HashMap has actually run? A more detailed look at the HashMap example reveals that what&#8217;s actually happening there, is the creation of a subclass of HashMap. This explains why the init-block runs after the constructor of HashMap: The init-block of the subclass is prepended to the constructor of the subclass, and the constructor of a subclass always runs after the constructor of its superclass.</p>
<p>A practical test confirms the following execution order of init-blocks and constructors:</p>
<p>- superclass init block<br />
- superclass constructor<br />
- your init block<br />
- your constructor</p>
<p>You can also define multiple init-blocks, the runtime system guarantees they execute in the order that they appear in the source code. So all in all the init-blocks are a nice (and widely unknown) language feature which can be used to add general initialization to all constructors or in special cases to replace a no-argument constructor.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.celerity.nl/blog/2008/11/fun-with-initialization-blocks/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Creating a Map in &#8220;Ruby-style&#8221; in Java</title>
		<link>http://www.celerity.nl/blog/2008/11/creating-a-map-in-ruby-style-in-java/</link>
		<comments>http://www.celerity.nl/blog/2008/11/creating-a-map-in-ruby-style-in-java/#comments</comments>
		<pubDate>Mon, 03 Nov 2008 16:21:19 +0000</pubDate>
		<dc:creator>Tomas Salfischberger</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.celerity.nl/blog/2008/11/creating-a-map-in-ruby-style-in-java/</guid>
		<description><![CDATA[With Ruby on Rails gaining popularity more and more people post comments about how awkward coding in Java (or .NET for that matter) is. Someone tried to explain why Java is this bad by explaining how PHP and Ruby can instantiate a Map of string and value pairs (called array in PHP). The syntax to [...]]]></description>
			<content:encoded><![CDATA[<p>With Ruby on Rails gaining popularity more and more people post comments about how awkward coding in Java (or .NET for that matter) is. Someone tried to explain why Java is this bad by explaining how PHP and Ruby can instantiate a Map of string and value pairs (called array in PHP). The syntax to define a Map in Ruby would be:</p>
<pre>{
    "name" =&gt; "Tomas Salfischberger",
    "phone" =&gt; "123456789",
    "room" =&gt; "11b"
}</pre>
<p>And for PHP:</p>
<pre>array(
    "name" =&gt; "Tomas Salfischberger",
    "phone" =&gt; "123456789",
    "room" =&gt; "11b"
)</pre>
<p>Now the problem with a lot of these comments is that most Java-critics can&#8217;t actually write proper Java code. There is, for example, the following method to instantiate the same Map in Java:</p>
<pre>new HashMap() {{
    put("name", "Tomas Salfischberger");
    put("phone", "123456789");
    put("room", "11b");
}}</pre>
<p>It is true that there is a bit more typing involved, but how many seconds does this actually cost you? And what if you look at the extra information we have provided? In Java we have actually expressed that we need a HashMap and not for example a TreeMap. That is not just more typing because Java programmers like typing, it&#8217;s actually valuable information.</p>
<p>Another one which might be useful (but more widely known I guess?) is this function to create a List using the Java 5 <a href="http://java.sun.com/j2se/1.5.0/docs/guide/language/varargs.html">varargs</a> feature:</p>
<pre>Arrays.asList("value1", "value2", "something else")</pre>
<p>These are both just simple tricks to make a programmer&#8217;s life easier, unfortunately a lot of people don&#8217;t know about them. Let&#8217;s hope the lost Ruby souls will some day find out about the simple tricks in other languages <img src='http://www.celerity.nl/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.celerity.nl/blog/2008/11/creating-a-map-in-ruby-style-in-java/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Simple plugins with BeanShell scripts</title>
		<link>http://www.celerity.nl/blog/2008/05/simple-plugins-with-beanshell-scripts/</link>
		<comments>http://www.celerity.nl/blog/2008/05/simple-plugins-with-beanshell-scripts/#comments</comments>
		<pubDate>Mon, 26 May 2008 16:03:06 +0000</pubDate>
		<dc:creator>Tomas Salfischberger</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.celerity.nl/blog/2008/05/simple-plugins-with-beanshell-scripts/</guid>
		<description><![CDATA[I was looking for a way to add a simple configurable extension-point to an application. The target was to be able to write a few lines of code or configure a few properties to be able to setup custom-filters. Luckily the task was not to be executed by a user of the system, but by [...]]]></description>
			<content:encoded><![CDATA[<p>I was looking for a way to add a simple configurable extension-point to an application. The target was to be able to write a few lines of code or configure a few properties to be able to setup custom-filters. Luckily the task was not to be executed by a user of the system, but by a programmer. The open source product of choice here was <a href="http://www.beanshell.org/">BeanShell</a>.</p>
<p>Here is an example of the code used to execute a simple script and give it access to part of the service-layer of the application:</p>
<pre>
Interpreter interpreter = new Interpreter();
interpreter.set("log", log);
interpreter.set("xxxxService", xxxxService);
interpreter.set("yyyyService", yyyyService);
interpreter.set("inputObject", someObject);
interpreter.eval(script);</pre>
<p>After which it is possible to write scripts in the BeanShell language (which is very much like Java) to modify the object inputted, or as in my case validate some business-rules by making a few service-calls.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.celerity.nl/blog/2008/05/simple-plugins-with-beanshell-scripts/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Security implications of the Spring DataBinder</title>
		<link>http://www.celerity.nl/blog/2008/04/security-implications-of-the-spring-databinder/</link>
		<comments>http://www.celerity.nl/blog/2008/04/security-implications-of-the-spring-databinder/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 16:14:59 +0000</pubDate>
		<dc:creator>Tomas Salfischberger</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.celerity.nl/blog/2008/04/security-implications-of-the-spring-databinder/</guid>
		<description><![CDATA[Today I was reviewing the security of a simple business application and found the following (simplified) controller:
public class UserEditController extends CancellableFormController {
    protected SecurityService securityService;

    protected ModelAndView onSubmit(...) throws Exception {
        User user = (User)command;
        [...]]]></description>
			<content:encoded><![CDATA[<p>Today I was reviewing the security of a simple business application and found the following (simplified) controller:</p>
<pre>public class UserEditController extends CancellableFormController {
    protected SecurityService securityService;

    protected ModelAndView onSubmit(...) throws Exception {
        User user = (User)command;
        securityService.updateUser(user);

        return getSuccessView();
    }

    @Required
    public void setSecurityService(SecurityService securityService) {
        this.securityService = securityService;
    }
}</pre>
<p>At first sight this seems a very common form-controller to edit a User object. The problem lies here in the fact that the User object has a few properties like &#8220;expireDate&#8221; and &#8220;accessLevel&#8221;. Experienced Spring users might see the security-problem now, others should check out the <a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/validation/DataBinder.html">documentation</a> for a hint:</p>
<p class="quote">Note that there are potential security implications in failing to set an array of allowed fields. In the case of HTTP form POST data for example, malicious clients can attempt to subvert an application by supplying values for fields or properties that do not exist on the form.</p>
<p>If you don&#8217;t set the allowedFields or disallowedFields property the DataBinder will bind all HTTP-parameters to the domainobject so a malicious user could post an accessLevel property changing their own accessLevel. Of course setting allowedFields everywhere seems like a lot of work, but Spring has made this quite easy. From the documentation:</p>
<p class="quote">Register fields that should be allowed for binding. Default is all fields. Restrict this for example to avoid unwanted modifications by malicious users when binding HTTP request parameters.Supports &#8220;xxx*&#8221;, &#8220;*xxx&#8221; and &#8220;*xxx*&#8221; patterns. More sophisticated matching can be implemented by overriding the isAllowed method.</p>
<p>So with these patterns there is no excuse to not restrict the properties to be bound.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.celerity.nl/blog/2008/04/security-implications-of-the-spring-databinder/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Maven tomcat:run and context.xml</title>
		<link>http://www.celerity.nl/blog/2008/04/maven-tomcatrun-and-context-xml/</link>
		<comments>http://www.celerity.nl/blog/2008/04/maven-tomcatrun-and-context-xml/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 14:40:45 +0000</pubDate>
		<dc:creator>Tomas Salfischberger</dc:creator>
		
		<category><![CDATA[Maven]]></category>

		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.celerity.nl/blog/2008/04/maven2-tomcatrun-and-jndi/</guid>
		<description><![CDATA[I ran into a problem today: When using the command mvn tomcat:run (the maven tomcat plugin) to quickly run a Tomcat instance and edit some JSPs on the fly I noticed my application was unable to find it&#8217;s JNDI defined DataSource:
javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
But this DataSource is defined in the [...]]]></description>
			<content:encoded><![CDATA[<p>I ran into a problem today: When using the command mvn tomcat:run (the maven tomcat plugin) to quickly run a Tomcat instance and edit some JSPs on the fly I noticed my application was unable to find it&#8217;s JNDI defined DataSource:</p>
<pre>javax.naming.NameNotFoundException: Name jdbc is not bound in this Context</pre>
<p>But this DataSource is defined in the src/main/webapp/META-INF/context.xml default context file:</p>
<pre>&lt;Context&gt;
        &lt;Resource name="jdbc/dbname" auth="Container" type="javax.sql.DataSource"
                maxActive="100" maxIdle="30" maxWait="10000"
                username="username" password="pass" driverClassName="com.mysql.jdbc.Driver"
                url="jdbc:mysql://localhost/dbname?autoReconnect=true"/&gt;
&lt;/Context&gt;</pre>
<p>So I searched the web for other people with these kind of issues and found a few mailinglist questions (all unanswered) <a href="http://www.mail-archive.com/users@maven.apache.org/msg83214.html">here</a> and <a href="http://www.nabble.com/Maven-Tomcat-plugin-with-custom-server.xml-td16029997s177.html">here</a>. And finally found out that it is just not possible to use a context.xml with the tomcat:run goal as it is still an open issue in the codehaus JIRA: <a href="http://jira.codehaus.org/browse/MOJO-594">#MOJO-594</a>. So I hope this might save someone some time searching for how to get tomcat to pickup the context.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.celerity.nl/blog/2008/04/maven-tomcatrun-and-context-xml/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Exporting Spring beans with XML-RPC</title>
		<link>http://www.celerity.nl/blog/2008/03/exporting-springbeans-with-xml-rpc/</link>
		<comments>http://www.celerity.nl/blog/2008/03/exporting-springbeans-with-xml-rpc/#comments</comments>
		<pubDate>Fri, 28 Mar 2008 13:57:44 +0000</pubDate>
		<dc:creator>Tomas Salfischberger</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.celerity.nl/blog/2008/04/exporting-springbeans-with-xml-rpc/</guid>
		<description><![CDATA[On a recent project I had to create an XML-RPC interface to some of the services we had in the business-layer of our application. The first thing to do is of course check out the Spring manual on remoting but to my surprise Spring doesn&#8217;t support XML-RPC natively. Googling for &#8220;Spring XML-RPC&#8221; I found a [...]]]></description>
			<content:encoded><![CDATA[<p>On a recent project I had to create an XML-RPC interface to some of the services we had in the business-layer of our application. The first thing to do is of course check out the <a href="http://static.springframework.org/spring/docs/2.5.x/reference/remoting.html">Spring manual on remoting</a> but to my surprise Spring doesn&#8217;t support XML-RPC natively. Googling for &#8220;Spring XML-RPC&#8221; I found a lot of blogposts and articles about integrating the Apache XML-RPC library with Spring, but part of them describe methods that just don&#8217;t work and others take a rather complicated approach where I would like to be able to just map a service-name to a Spring bean.</p>
<p>After this rather unsatisfactory search I decided to checkout how hard it would be to integrate Apache XML-RPC with Spring in the way I just described. The target is to be able to write something like the following Spring configuration to be able to export some services:</p>
<pre>&lt;bean name="serviceExporter" class="..."&gt;
    &lt;property name="services"&gt;
        &lt;map&gt;
            &lt;entry key="ExampleService" value-ref="exampleServiceBean" /&gt;
        &lt;/map&gt;
    &lt;/property&gt;
&lt;/bean&gt;</pre>
<p>Perry Nguyen has written a <a href="http://www.hanhuy.com/pfn/ws-xmlrpc-and-spring">post</a> about integrating Apache XML-RPC 3 with Spring but he has left some open ends in my opinion. His solution is like mine based on a map of beans to be used in a ProcessorFactoryFactory. The first step in handling an XML-RPC request is mapping the request to a simple controller:</p>
<pre>public class XmlRpcController extends AbstractController {
    private XmlRpcServletServer server = new XmlRpcServletServer();

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse res) throws Exception {
        <span class="commented">// Delegate the request to the XmlRpcServletServer</span>
        server.execute(req, res);
        <span class="commented">// And stop processing of the request</span>
        return null;
    }

    @Required
    public void setMapping(XmlRpcHandlerMapping mapping) {
        server.setHandlerMapping(mapping);
    }
}</pre>
<p>As you can see this is just a simple wrapper around the XmlRpcServletServer to pass the request and response to the execute method. Apart from that we have a mapping property to set the handlerMapping property on the server. The next step is to create our own mapping class to be able to map service-names to a class:</p>
<pre>public class SimpleHandlerMapping extends AbstractReflectiveHandlerMapping {
    public void setServices(Map&lt;String, Object&gt; services) throws XmlRpcException {
        <span class="commented">// Check parameter</span>
        Assert.notNull(services, &#8220;Services map should not be null.&#8221;);

        <span class="commented">// Setup a RequestProcessorFactoryFactory</span>
        SimpleRequestProcessorFactoryFactory factory = new SimpleRequestProcessorFactoryFactory();

        <span class="commented">// Register all service beans with the factory</span>
        for (Object serviceBean : services.values()) {
        	factory.registerServiceBean(serviceBean.getClass(), serviceBean);
        }

        <span class="commented">// Set the RequestFactoryFactory to be used for mapping</span>
        setRequestProcessorFactoryFactory(factory);

        <span class="commented">// Loop through the set</span>
        Iterator&lt;Entry&lt;String, Object&gt;&gt; it = services.entrySet().iterator();
        while (it.hasNext()) {
            <span class="commented">// Fetch from the map</span>
            Entry&lt;String, Object&gt; entry = it.next();
            String serviceName = entry.getKey();
            Object serviceBean = entry.getValue();

            <span class="commented">// Register service in the handler mapping</span>
            registerPublicMethods(serviceName, serviceBean.getClass());
        }
    }
}</pre>
<p>The input of this mapper is a simple Map of Strings and Objects describing the service-names associated with the objects (Spring beans). First we create a RequestProcessorFactoryFactory to be able to map classnames to Spring beans the code for this SimpleRequestProcessorFactoryFactory is given below. Then we register all services in the Map with the factory and set the factory to be used by the methods from our superclass.</p>
<p>The last step is to register all service-names with their respective classes using the registerPublicMethods method from our superclass. This tells Apache XML-RPC to register all public methods and call our SimpleRequestProcessorFactoryFactory to get a Factory returning the servicebean. This SimpleRequestProcessorFactoryFactory is based on a Map of Class and Objects to map the Class Apache XML-RPC asks for to a Spring bean:</p>
<pre>public class SimpleRequestProcessorFactoryFactory implements RequestProcessorFactoryFactory {
    private Map&lt;Class, Object&gt; serviceBeans = new HashMap&lt;Class, Object&gt;();

    public RequestProcessorFactory getRequestProcessorFactory(Class pClass) throws XmlRpcException {
        <span class="commented">// Get the serviceBean from the map</span>
        final Object serviceBean = serviceBeans.get(pClass);

        <span class="commented">// Check if the bean is actually found</span>
        if (serviceBean == null) {
            throw new XmlRpcException(&#8221;Handler \&#8221;" + pClass.getCanonicalName() + &#8220;\&#8221; not found.&#8221;);
        }

        <span class="commented">// Create a factory just returning the lookedup bean</span>
        return new RequestProcessorFactory() {
            public Object getRequestProcessor(XmlRpcRequest pRequest) throws XmlRpcException {
                return serviceBean;
            }
        };
    }

    public void registerServiceBean(Class clazz, Object serviceBean) {
    	serviceBeans.put(clazz, serviceBean);
    }
}</pre>
<p>And then just a few lines of XML to wire it all together:</p>
<pre>&lt;bean id="xmlRpcHandlerMapping" class="nl.celerity.example.xmlrpc.SimpleHandlerMapping"&gt;
    &lt;property name="services"&gt;
        &lt;map&gt;
            &lt;entry key="ExampleService" value-ref="exampleService" /&gt;
        &lt;/map&gt;
    &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="xmlRpcController" class="nl.celerity.example.xmlrpc.XmlRpcController"&gt;
    &lt;property name="mapping" ref="xmlRpcHandlerMapping" /&gt;
&lt;/bean&gt;</pre>
<p>Where exampleService is of course the name of a Spring bean with some public methods to be exported. With these two simple helper classes and an extremely simple controller we have the ability to export Spring beans as XML-RPC services by just adding a simple line of XML configuration.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.celerity.nl/blog/2008/03/exporting-springbeans-with-xml-rpc/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Nieuwe website</title>
		<link>http://www.celerity.nl/blog/2008/03/nieuwe-website/</link>
		<comments>http://www.celerity.nl/blog/2008/03/nieuwe-website/#comments</comments>
		<pubDate>Mon, 10 Mar 2008 12:07:49 +0000</pubDate>
		<dc:creator>Tomas Salfischberger</dc:creator>
		
		<category><![CDATA[Nieuws]]></category>

		<guid isPermaLink="false">http://www.celerity.nl/blog/2008/03/new-website/</guid>
		<description><![CDATA[Vanaf vandaag hebben wij onze oude SHC website vervangen door een vernieuwde Celerity ICT versie. De nieuwe website is de laatste stap in de overgang van SHC naar Celerity ICT.
Deze verandering werd deels geïnitieerd door het feit dat de H in SHC stond voor Henschen, en John Henschen zich enige tijd geleden vanwegen persoonlijke omstandigheden [...]]]></description>
			<content:encoded><![CDATA[<p>Vanaf vandaag hebben wij onze oude SHC website vervangen door een vernieuwde Celerity ICT versie. De nieuwe website is de laatste stap in de overgang van SHC naar Celerity ICT.</p>
<p>Deze verandering werd deels geïnitieerd door het feit dat de H in SHC stond voor Henschen, en John Henschen zich enige tijd geleden vanwegen persoonlijke omstandigheden uit het bedrijf heeft teruggetrokken. De belangrijkste aanzet voor deze verandering was echter het feit dat SHC is gegroeid van hoofdzakelijk een netwerk solutions provider naar een groeiende speler op de markt van softwareontwikkeling.</p>
<p>Een nieuw onderdeel van deze website is onze <a href="/blog/">blog</a> of <a href="/blog/">weblog</a>, vooral bedoeld om een platform te vormen voor publicatie van informatie over de technieken die wij gebruiken en een mogelijkheid om deze informatie te delen met beroepsgenoten. Dit onderdeel zal in het Engels beschikbaar zijn, omdat deze technieken internationaal gebruikt worden en de informatie daarmee universeel is voor het gehele vakgebied.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.celerity.nl/blog/2008/03/nieuwe-website/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Nieuw algemeen telefoonnummer</title>
		<link>http://www.celerity.nl/blog/2008/02/algemeen-telefoonnummer/</link>
		<comments>http://www.celerity.nl/blog/2008/02/algemeen-telefoonnummer/#comments</comments>
		<pubDate>Thu, 14 Feb 2008 16:13:51 +0000</pubDate>
		<dc:creator>Arthur Vlug</dc:creator>
		
		<category><![CDATA[Nieuws]]></category>

		<guid isPermaLink="false">http://www.celerity.nl/blog/2008/03/general-contact-information/</guid>
		<description><![CDATA[Omdat we onderling steeds meer telefoontjes moeten doorverbinden en vooral onze grotere klanten daardoor niet direct de juiste persoon kunnen bereiken hebben we een nieuw algemeen telefoonnummer ingesteld: (+31) 030-8007731. U kunt ons bereiken op werkdagen van 09:00 tot 17:30.
]]></description>
			<content:encoded><![CDATA[<p>Omdat we onderling steeds meer telefoontjes moeten doorverbinden en vooral onze grotere klanten daardoor niet direct de juiste persoon kunnen bereiken hebben we een nieuw algemeen telefoonnummer ingesteld: (+31) 030-8007731. U kunt ons bereiken op werkdagen van 09:00 tot 17:30.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.celerity.nl/blog/2008/02/algemeen-telefoonnummer/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Uitbreiding van het team</title>
		<link>http://www.celerity.nl/blog/2008/01/introducing-a-new-team-member/</link>
		<comments>http://www.celerity.nl/blog/2008/01/introducing-a-new-team-member/#comments</comments>
		<pubDate>Mon, 07 Jan 2008 08:33:31 +0000</pubDate>
		<dc:creator>Koen Bos</dc:creator>
		
		<category><![CDATA[Nieuws]]></category>

		<guid isPermaLink="false">http://www.celerity.nl/blog/2008/01/introducing-a-new-team-member/</guid>
		<description><![CDATA[In de afgelopen maanden hebben we een flinke groei in projecten doorgemaakt. Om ervoor te zorgen dat de huidige en toekomstige projecten naar volle tevredenheid van onze klanten kunnen worden uitgevoerd is ons team uitgebreid met Arthur Vlug.
Arthur zal zich gaan richten op het verbeteren van de gebruiksvriendelijkheid van de geavanceerde functionaliteit van Celerity CRM [...]]]></description>
			<content:encoded><![CDATA[<p>In de afgelopen maanden hebben we een flinke groei in projecten doorgemaakt. Om ervoor te zorgen dat de huidige en toekomstige projecten naar volle tevredenheid van onze klanten kunnen worden uitgevoerd is ons team uitgebreid met <a href="/arthur/">Arthur Vlug</a>.</p>
<p>Arthur zal zich gaan richten op het verbeteren van de gebruiksvriendelijkheid van de geavanceerde functionaliteit van Celerity CRM en het exporteren van data naar Microsoft Office formaten.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.celerity.nl/blog/2008/01/introducing-a-new-team-member/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

