<?xml version="1.0" encoding="UTF-8"?>
<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/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Vonk's Blog &#187; wicket</title>
	<atom:link href="http://blog.larsvonkconsultancy.nl/tag/wicket/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.larsvonkconsultancy.nl</link>
	<description>Blogs about Software Development, Agility and all the Rest</description>
	<lastBuildDate>Fri, 31 Jul 2009 13:51:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>The Power of ClassPathScanningCandidateComponentProvider</title>
		<link>http://blog.larsvonkconsultancy.nl/2009/01/the-power-of-classpathscanningcandidatecomponentprovider/</link>
		<comments>http://blog.larsvonkconsultancy.nl/2009/01/the-power-of-classpathscanningcandidatecomponentprovider/#comments</comments>
		<pubDate>Fri, 30 Jan 2009 16:26:42 +0000</pubDate>
		<dc:creator>Lars Vonk</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[wicket]]></category>

		<guid isPermaLink="false">http://lvonk.wordpress.com/?p=51</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>Recently I found out about Springs <a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.html" onclick="pageTracker._trackPageview('/outgoing/static.springframework.org/spring/docs/2.5.x/api/org/springframework/context/annotation/ClassPathScanningCandidateComponentProvider.html?referer=');">ClassPathScanningCandidateComponentProvider</a>. This class allows you to scan the classpath from a base package at runtime. This is extremely handy in all kind of situations, for instances in testing.<br />
<span id="more-51"></span><br />
As an example scenario I have a secured webapplication, build with <a href="http://wicket.apache.org/" onclick="pageTracker._trackPageview('/outgoing/wicket.apache.org/?referer=');">Wicket</a>. All the <a href="http://wicket.sourceforge.net/apidocs/wicket/markup/html/WebPage.html" onclick="pageTracker._trackPageview('/outgoing/wicket.sourceforge.net/apidocs/wicket/markup/html/WebPage.html?referer=');">WebPage</a>s need to be secured using the <a href="http://cwiki.apache.org/WICKET/acegi-and-wicket-auth-roles.html" onclick="pageTracker._trackPageview('/outgoing/cwiki.apache.org/WICKET/acegi-and-wicket-auth-roles.html?referer=');">wicket-auth-roles</a>. We can test this by creating a junit test using WicketTester and assert that is we want to start a secured page it will actually open the LoginPage. This will work, but it needs to be repeated for all new secure WebPages. This is of course cumbersome and it is highly likely we will forget to add a test for the next WebPage we will create.<br />
Better is to use the power of the ClassPathScanningCandidateComponentProvider. With this class we can simply scan the classpath and look for WebPages in the admin package and check if they are annotated with the @AuthorizeInstantiation annotation.</p>
<pre class="brush: java;">
   @Test
    public void shouldSecureAllPagesInAdminPackageExceptTheLoginPage() throws Exception {
        ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
        provider.addIncludeFilter(new NonSecuredWebPagesFilter(LoginPage.class));
        Set components = provider.findCandidateComponents(&quot;nl.ns.campaigns.admin.web&quot;);
        assertEquals(0, components.size());
    }
</pre>
<p>The idea of this test is that it should not find classes that extend WebPage and that are not annotated with @AuthorizeInstantiation. If we do find one, the test will fail.<br />
The logic match is implemented in a TypeFilter, in this case the custom NonSecuredWebPagesFilter. The code of the TypeFilter looks like this:</p>
<pre class="brush: java;">
    private static final class NonSecuredWebPagesFilter implements TypeFilter {
        private final Class loginPage;
        public NonSecuredWebPagesFilter(Class loginPage) {
            this.loginPage = loginPage;
        }
        public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
            boolean hasAnnotation = false;
            boolean isWebPage = false;
            boolean isLoginPage = false;
            try {
                String className = metadataReader.getClassMetadata().getClassName();
                Class clazz = Class.forName(className);
                isLoginPage = loginPage.equals(clazz);
                isWebPage = WebPage.class.isAssignableFrom(clazz);
                hasAnnotation = clazz.isAnnotationPresent(AuthorizeInstantiation.class);
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(e);
            }
            return !hasAnnotation &amp;&amp; isWebPage &amp;&amp; !isLoginPage;
        }
    }
</pre>
<p>Since the LoginPage does not have to be annotated we exclude it from our search. Only WebPages that are not annotated are returned due to this TypeFilter.</p>
<p>Scanning the classpath has become a piece of cake using the ClassPathScanningCandidateComponentProvider and I am sure there are many more usecases for this class.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.larsvonkconsultancy.nl/2009/01/the-power-of-classpathscanningcandidatecomponentprovider/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
