<?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>Lukasz Baran Blog</title>
	<atom:link href="http://lukaszbaran.com/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://lukaszbaran.com/blog</link>
	<description>programming tips, tricks &#38; scraps</description>
	<lastBuildDate>Wed, 25 Apr 2012 14:31:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Useful XSLT snippet with translate()</title>
		<link>http://lukaszbaran.com/blog/?p=479</link>
		<comments>http://lukaszbaran.com/blog/?p=479#comments</comments>
		<pubDate>Wed, 25 Apr 2012 14:09:29 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lukaszbaran.com/blog/?p=479</guid>
		<description><![CDATA[Let&#8217;s say there is a following function written in XSLT 2.0:     &#60;xsl:function name="str:convertBits"&#62;         &#60;xsl:param name="cpnNumber" /&#62;         &#60;xsl:choose&#62;             &#60;xsl:when test="$cpnNumber = 1"&#62;                 &#60;xsl:value-of&#62;8&#60;/xsl:value-of&#62;             &#60;/xsl:when&#62;             &#60;xsl:when test="$cpnNumber = 2"&#62;                 &#60;xsl:value-of&#62;4&#60;/xsl:value-of&#62;             &#60;/xsl:when&#62;             &#60;xsl:when test="$cpnNumber = 3"&#62;                 &#60;xsl:value-of&#62;2&#60;/xsl:value-of&#62;             &#60;/xsl:when&#62;             &#60;xsl:when test="$cpnNumber = 4"&#62;                &#60;xsl:value-of&#62;1&#60;/xsl:value-of&#62;             [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say there is a following function written in XSLT 2.0:</p>
<pre>    &lt;xsl:function name="str:convertBits"&gt;
        &lt;xsl:param name="cpnNumber" /&gt;

        &lt;xsl:choose&gt;
            &lt;xsl:when test="$cpnNumber = 1"&gt;
                &lt;xsl:value-of&gt;8&lt;/xsl:value-of&gt;
            &lt;/xsl:when&gt;
            &lt;xsl:when test="$cpnNumber = 2"&gt;
                &lt;xsl:value-of&gt;4&lt;/xsl:value-of&gt;
            &lt;/xsl:when&gt;
            &lt;xsl:when test="$cpnNumber = 3"&gt;
                &lt;xsl:value-of&gt;2&lt;/xsl:value-of&gt;
            &lt;/xsl:when&gt;
            &lt;xsl:when test="$cpnNumber = 4"&gt;
               &lt;xsl:value-of&gt;1&lt;/xsl:value-of&gt;
            &lt;/xsl:when&gt;
            &lt;xsl:otherwise&gt;
               &lt;xsl:value-of&gt;0&lt;/xsl:value-of&gt;
            &lt;/xsl:otherwise&gt;
        &lt;/xsl:choose&gt;
    &lt;/xsl:function&gt;</pre>
<p>Quite long, isn&#8217;t it?</p>
<p>This is how it can be shortened:</p>
<blockquote>
<pre>number(translate(xs:string($cpnNumbers[1]), '1234567890', '8421000000'))</pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://lukaszbaran.com/blog/?feed=rss2&#038;p=479</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to speed up maven clean install?</title>
		<link>http://lukaszbaran.com/blog/?p=474</link>
		<comments>http://lukaszbaran.com/blog/?p=474#comments</comments>
		<pubDate>Mon, 20 Feb 2012 17:15:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lukaszbaran.com/blog/?p=474</guid>
		<description><![CDATA[This post will be very short. If you often find yourself idly waiting for mvn clean compile command to finish, then you probably need to get familiar with mvnsh tool. I tried mvnsh in my work and the first glance the time of compilation was reduced about 50%.]]></description>
			<content:encoded><![CDATA[<p>This post will be very short.</p>
<p>If you often find yourself idly waiting for <strong>mvn clean compile</strong> command to finish, then you probably need to get familiar with <a href="http://shell.sonatype.org/" target="_blank">mvnsh</a> tool. I tried mvnsh in my work and the first glance the time of compilation was reduced about 50%.</p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszbaran.com/blog/?feed=rss2&#038;p=474</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to change XML to lower case using XSLT multi-pass?</title>
		<link>http://lukaszbaran.com/blog/?p=467</link>
		<comments>http://lukaszbaran.com/blog/?p=467#comments</comments>
		<pubDate>Fri, 17 Feb 2012 12:07:16 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lukaszbaran.com/blog/?p=467</guid>
		<description><![CDATA[Today I&#8217;ve resolved another issue using XSLT multi-pass technique presented in my previous post. I think this be might useful in future, so I post it here. The XSLT translates the input XML to lower case (it changes only node names, it doesn&#8217;t affect data inside elements or attributes). After that, it applies the actual [...]]]></description>
			<content:encoded><![CDATA[<p>Today I&#8217;ve resolved another issue using XSLT multi-pass technique presented in <a title="How to get rid of empty attributes in XSLT output?" href="http://lukaszbaran.com/blog/?p=437">my previous post</a>. I think this be might useful in future, so I post it here. The XSLT translates the input XML to lower case (it changes only node names, it doesn&#8217;t affect data inside elements or attributes). After that, it applies the actual logic.</p>
<pre class="brush: xml; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;&gt;
&lt;xsl:variable name=&quot;firstPassResult&quot;&gt;
&lt;xsl:apply-templates select=&quot;/&quot; mode=&quot;firstPass&quot;/&gt;
&lt;/xsl:variable&gt;
&lt;xsl:template match=&quot;@*|node()&quot; mode=&quot;firstPass&quot;&gt;
&lt;xsl:copy&gt;
&lt;xsl:apply-templates select=&quot;@*|node()&quot;/&gt;
&lt;/xsl:copy&gt;
&lt;/xsl:template&gt;
&lt;xsl:template match=&quot;*&quot; mode=&quot;firstPass&quot;&gt;
&lt;xsl:element name=&quot;{translate(name(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz')}&quot;&gt;
&lt;xsl:apply-templates select=&quot;@*|node()&quot;/&gt;
&lt;/xsl:element&gt;
&lt;/xsl:template&gt;
&lt;xsl:template match=&quot;/&quot;&gt;
&lt;xsl:apply-templates select=&quot;$firstPassResult&quot; mode=&quot;secondPass&quot;/&gt;
&lt;/xsl:template&gt;
&lt;xsl:template match=&quot;//boss&quot; mode=&quot;secondPass&quot;&gt;
&lt;xsl:value-of select=&quot;text()&quot;/&gt;
&lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
</pre>
<p>The sample XML file (only to prove that this technique works):</p>
<pre class="brush: xml; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;Root&gt;
&lt;Boss&gt;John&lt;/Boss&gt;
&lt;BoSs&gt;Henry&lt;/BoSs&gt;
&lt;BOSS&gt;Nathan&lt;/BOSS&gt;
&lt;boss&gt;igor&lt;/boss&gt;
&lt;/Root&gt;
</pre>
<p>It worked under Altova XMLSpy and produced the following output:</p>
<pre class="brush: xml; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;JohnHenryNathanigor</pre>
]]></content:encoded>
			<wfw:commentRss>http://lukaszbaran.com/blog/?feed=rss2&#038;p=467</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to get rid of empty attributes in XSLT output?</title>
		<link>http://lukaszbaran.com/blog/?p=437</link>
		<comments>http://lukaszbaran.com/blog/?p=437#comments</comments>
		<pubDate>Mon, 09 Jan 2012 11:42:56 +0000</pubDate>
		<dc:creator>lukaszb</dc:creator>
				<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[xslt]]></category>

		<guid isPermaLink="false">http://lukaszbaran.com/blog/?p=437</guid>
		<description><![CDATA[Some time ago, I faced an issue related to XSLT stylesheets. It was while we were developing quite complex XSLT template whose purpose was to convert one  XML  into completely different another one. During the implementation, it turned out that the output XML contains a lot unnecessary empty attributes, e.g.: &#60;field attr="" /&#62; It was [...]]]></description>
			<content:encoded><![CDATA[<p>Some time ago, I faced an issue related to XSLT stylesheets. It was while we were developing quite complex XSLT template whose purpose was to convert one  XML  into completely different another one. During the implementation, it turned out that the output XML contains a lot unnecessary <strong>empty</strong> attributes, e.g.:</p>
<pre>&lt;field attr="" /&gt;</pre>
<p>It was actually possible to get rid of them with &lt;xsl:if&gt; or &lt;xsl:choose&gt; instructions. However, it would require one conditional instruction per one &lt;xsl:attribute&#8230;/&gt; instruction. This would make the XSLT file too complex. So I needed other approach, that would act after the basic transform. And this is achievable by usage of</p>
<h2>multi-pass XSLT transforms.</h2>
<p>Let&#8217;s say that we have the following input XML:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=\&quot;1.0\&quot; encoding=\&quot;UTF-8\&quot;?&gt;
&lt;database&gt;
&lt;record firstName=\&quot;john\&quot; lastName=\&quot;smith\&quot;&gt;writer&lt;/record&gt;
&lt;/database&gt;
</pre>
<p>We would like to have the above XML converted by this XSLT transform:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;xsl:stylesheet version=&quot;2.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot; xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;
    &lt;xsl:output indent=&quot;yes&quot; exclude-result-prefixes=&quot;xs xsl&quot;/&gt;

    &lt;xsl:template match=&quot;/database/record&quot;&gt;
        &lt;output&gt;
            &lt;xsl:attribute name=&quot;firstName&quot;&gt;
                &lt;xsl:value-of select=&quot;@firstName&quot;/&gt;
            &lt;/xsl:attribute&gt;
            &lt;xsl:attribute name=&quot;lastName&quot;&gt;
                &lt;xsl:value-of select=&quot;@firstName&quot;/&gt;
            &lt;/xsl:attribute&gt;
            &lt;xsl:attribute name=&quot;middleName&quot;&gt;
                &lt;xsl:value-of select=&quot;@middleName&quot;/&gt;
            &lt;/xsl:attribute&gt;
            &lt;xsl:attribute name=&quot;dob&quot;&gt;
                &lt;xsl:value-of select=&quot;@dob&quot;/&gt;
            &lt;/xsl:attribute&gt;
            &lt;xsl:text&gt;recordFound&lt;/xsl:text&gt;
        &lt;/output&gt;
    &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
</pre>
<p>The output looks like this:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;output firstName=&quot;john&quot; lastName=&quot;john&quot; middleName=&quot;&quot; dob=&quot;&quot;&gt;recordFound&lt;/output&gt;
</pre>
<p>As you can see there are two empty attributes: <strong>middlename</strong> and <strong>dob</strong>. And this is where we can think about multi-pass transforms. We would like to have another transform applied on the results of the this XSLT.</p>
<p>Now, let&#8217;s consider what should be done to remove empty attributes. This is very to accomplish using identity transforms. This is simple variant of identity transform that removes empty attributes:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;xsl:stylesheet version=&quot;2.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot; xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;
    &lt;xsl:template match=&quot;node()|@*&quot; &gt;
        &lt;xsl:copy&gt;
             &lt;xsl:apply-templates select=&quot;@*[.!='']&quot; /&gt;
             &lt;xsl:apply-templates select=&quot;node()&quot; /&gt;
        &lt;/xsl:copy&gt;
    &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
</pre>
<p>What is left is merging our both  XSLTs. The following code is the final XSLT transformation. We are using modes that are available XSLT 2.0. We store the result of our business operation in the variable <strong>$firstPassResult</strong> and we perform the removal of empty attributes on it.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;xsl:stylesheet version=&quot;2.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot; xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;
    &lt;xsl:output indent=&quot;yes&quot; exclude-result-prefixes=&quot;xs xsl&quot;/&gt;
    &lt;xsl:variable name=&quot;firstPassResult&quot;&gt;
        &lt;xsl:apply-templates select=&quot;/&quot; mode=&quot;firstPass&quot; /&gt;
    &lt;/xsl:variable&gt;

    &lt;xsl:template match=&quot;/database/record&quot; mode=&quot;firstPass&quot;&gt;
        &lt;output&gt;
            &lt;xsl:attribute name=&quot;firstName&quot;&gt;
                &lt;xsl:value-of select=&quot;@firstName&quot;/&gt;
            &lt;/xsl:attribute&gt;
            &lt;xsl:attribute name=&quot;lastName&quot;&gt;
                &lt;xsl:value-of select=&quot;@firstName&quot;/&gt;
            &lt;/xsl:attribute&gt;
            &lt;xsl:attribute name=&quot;middleName&quot;&gt;
                &lt;xsl:value-of select=&quot;@middleName&quot;/&gt;
            &lt;/xsl:attribute&gt;
            &lt;xsl:attribute name=&quot;dob&quot;&gt;
                &lt;xsl:value-of select=&quot;@dob&quot;/&gt;
            &lt;/xsl:attribute&gt;
            &lt;xsl:text&gt;recordFound&lt;/xsl:text&gt;
        &lt;/output&gt;
    &lt;/xsl:template&gt;

    &lt;xsl:template match=&quot;/&quot;&gt;
        &lt;xsl:apply-templates select=&quot;$firstPassResult&quot;
            mode=&quot;secondPass&quot; /&gt;
    &lt;/xsl:template&gt;

    &lt;xsl:template match=&quot;node()|@*&quot; mode=&quot;secondPass&quot;&gt;
        &lt;xsl:copy&gt;
             &lt;xsl:apply-templates select=&quot;@*[.!='']&quot; mode=&quot;secondPass&quot;/&gt;
             &lt;xsl:apply-templates select=&quot;node()&quot; mode=&quot;secondPass&quot;/&gt;
        &lt;/xsl:copy&gt;
    &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://lukaszbaran.com/blog/?feed=rss2&#038;p=437</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>&#8220;Real programmers do not use Pascal&#8221;</title>
		<link>http://lukaszbaran.com/blog/?p=330</link>
		<comments>http://lukaszbaran.com/blog/?p=330#comments</comments>
		<pubDate>Thu, 31 Mar 2011 00:16:50 +0000</pubDate>
		<dc:creator>lukaszb</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lukaszbaran.com/blog/?p=330</guid>
		<description><![CDATA[I&#8217;ll bet that most of the readers of this blog have never read that article. To be honest I read it in 1993, when a Polish magazine about 8-bit Atari computers published its translation. I must admit that I didn&#8217;t realize how ironic it was when I read it for the first time. I was [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll bet that most of the readers of this blog have never read <a href="http://www.pbm.com/~lindahl/real.programmers.html">that article</a>. To be honest I read it in 1993, when a Polish magazine about 8-bit Atari computers published its translation.<br />
I must admit that I didn&#8217;t realize how ironic it was when I read it for the first time. I was convinced that the guy seriously tried to define and describe the Real Programmer. But it&#8217;s not important right now. Don&#8217;t you get an impression such attitude appears sometimes when you&#8217;re dealing with IT engineers, software developer or simply programmers? &#8220;Because&#8230; real programmers DO this and DO NOT DO this&#8230;&#8221; But if you could read their thoughts you&#8217;d know that the only thing that really matters is to express the superiority of MY EGO&#8230;</p>
<p>To be continued&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszbaran.com/blog/?feed=rss2&#038;p=330</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A piece of very old assembly code</title>
		<link>http://lukaszbaran.com/blog/?p=308</link>
		<comments>http://lukaszbaran.com/blog/?p=308#comments</comments>
		<pubDate>Tue, 29 Mar 2011 22:28:45 +0000</pubDate>
		<dc:creator>lukaszb</dc:creator>
				<category><![CDATA[Source code]]></category>
		<category><![CDATA[assembly]]></category>
		<category><![CDATA[demoscene]]></category>
		<category><![CDATA[intro]]></category>
		<category><![CDATA[memories]]></category>

		<guid isPermaLink="false">http://lukaszbaran.com/blog/?p=308</guid>
		<description><![CDATA[A couple of weeks ago I&#8217;ve been looking through some old backup CDs. To my surprise I have found some old source codes written more than 10 years ago. Of course, most of them were unfinished and ugly. Some of them turned out to be totally useless rubbish which made me feel embarrassed. But I [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of weeks ago I&#8217;ve been looking through some old backup CDs. To my surprise I have found some old source codes written more than 10 years ago. Of course, most of them were unfinished and ugly. Some of them turned out to be totally useless rubbish which made me feel embarrassed. But I have also found a couple of interesting things. For a moment I was amazed&#8230; I still cannot believe that I used to have so much patience to write code in pure assembler.<br />
<a href="http://lukaszbaran.com/blog/wp-content/uploads/2011/03/loser.zip">Here</a> is a sample source code. It was supposed to be <a href="http://en.wikipedia.org/wiki/Demo_(computer_programming)#Intros">a 4KB intro</a>.<br />
The intro was written in 1999 (a twilight of <a href="http://en.wikipedia.org/wiki/MS-DOS">MS-DOS</a> era) in pure 80&#215;86 assembly language. It should run on 32-bit Windows. The executable itself is 3529 bytes long and it is <a href="http://en.wikipedia.org/wiki/COM_file">.COM executable file</a>. Its name was supposed to be &#8220;Loser&#8221;, but I really do not remember why such a title was chosen. There were some nasty tricks used to make the code as short as possible&#8230; but who would care about them today? It doesn&#8217;t generate any sound effects or music, but trust me it was also possible in assembler! The visual effects were of course supposed to make an impression of a damaged TV-set (so please do not adjust your monitor:).<br />
I have recorded and uploaded this animation on YouTube:</p>
<p><iframe title="YouTube video player" width="480" height="390" src="http://www.youtube.com/embed/PoP8EXpi_7w" frameborder="0" allowfullscreen></iframe></p>
<p>If you would like to compile source code of this &#8220;demo&#8221; you should use Borland&#8217;s <a href="http://en.wikipedia.org/wiki/Turbo_Assembler">Turbo Assembler</a> and Turbo Linker. </p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszbaran.com/blog/?feed=rss2&#038;p=308</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Problem: MS Office Communicator 2005 fails to install</title>
		<link>http://lukaszbaran.com/blog/?p=300</link>
		<comments>http://lukaszbaran.com/blog/?p=300#comments</comments>
		<pubDate>Thu, 17 Feb 2011 11:57:08 +0000</pubDate>
		<dc:creator>lukaszb</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://lukaszbaran.com/blog/?p=300</guid>
		<description><![CDATA[In my current company, I&#8217;m forced to use IM which is MS Office Communicator 2005. Accidentally (or perhaps my tortured subconsciousness told me do so;), I uninstalled this thing. Unfortunately, re-installation of this application wasn&#8217;t so easy as it seemed to be. When I ran installer it exited saying that Communicator could not be installed. [...]]]></description>
			<content:encoded><![CDATA[<p>In my current company, I&#8217;m forced to use IM which is MS Office Communicator 2005. Accidentally (or perhaps my tortured subconsciousness told me do so;), I uninstalled this thing. Unfortunately, re-installation of this application wasn&#8217;t so easy as it seemed to be. When I ran installer it exited saying that Communicator could not be installed. That was really strange. After a couple of hours, I&#8217;ve finally realized that configuration of my workstation doesn&#8217;t really differ from the configuration of a typical WinXP machine, so the problem may be in some service pack or some security update. And that was it. A little creature named &#8220;Security Update KB974571&#8243; was the reason causing the failure (it was enough to uninstall it and reboot the computer). I wasted about 4 hours of my life which could be spent on coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszbaran.com/blog/?feed=rss2&#038;p=300</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Back</title>
		<link>http://lukaszbaran.com/blog/?p=267</link>
		<comments>http://lukaszbaran.com/blog/?p=267#comments</comments>
		<pubDate>Thu, 28 Oct 2010 23:55:48 +0000</pubDate>
		<dc:creator>lukaszb</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[webdesign]]></category>

		<guid isPermaLink="false">http://lukaszbaran.com/blog/?p=267</guid>
		<description><![CDATA[Apart from programming in Java/C# from time to time I do some small side projects such as webpages. I have never considered myself as a real webmaster. For me, languages like PHP cannot be classified as programming languages. However, I have always admired well-designed websites and I regret that I am not so talented. That [...]]]></description>
			<content:encoded><![CDATA[<p>Apart from programming in Java/C# from time to time I do some small side projects such as webpages. I have never considered myself as a real webmaster. For me, languages like PHP cannot be classified as programming languages. However, I have always admired well-designed websites and I regret that I am not so talented. That is why I sometimes try to design a web page &#8211; just to make sure that I am better at programming than web design.<br />
Here is a project I did a couple weeks ago. It is a web page for a radiology laboratory. All the work (design &#038; PHP code) is mine; I did not use any templates. OK, you can now make use of your rotten tomatoes.</p>
<p><a href="http://radiologica-rzeszow.com.pl?lang=en"><img src="http://lukaszbaran.com/blog/wp-content/uploads/2010/11/rr-english-small.jpg" alt="Radiologica-Rzeszow Website" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszbaran.com/blog/?feed=rss2&#038;p=267</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>NHibernate SchemaValidator reimplemented.</title>
		<link>http://lukaszbaran.com/blog/?p=216</link>
		<comments>http://lukaszbaran.com/blog/?p=216#comments</comments>
		<pubDate>Thu, 07 Jan 2010 12:07:39 +0000</pubDate>
		<dc:creator>lukaszb</dc:creator>
				<category><![CDATA[Hints]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[nhibernate]]></category>
		<category><![CDATA[tips & tricks]]></category>

		<guid isPermaLink="false">http://lukaszbaran.com/blog/?p=216</guid>
		<description><![CDATA[Some time ago a new utility class was introduced to NHibernate. It&#8217;s called SchemaValidator and it allows you to detect inconsistencies between mappings and database schema. Here you can find a short sample code showing how it works. The class has got only one useful method called Validate(). It analyzes and compares database metadata with [...]]]></description>
			<content:encoded><![CDATA[<p>Some time ago a new utility class was introduced to NHibernate. It&#8217;s called <strong>SchemaValidator </strong>and it allows you to detect inconsistencies between mappings and database schema. <a href="http://nhforge.org/blogs/nhibernate/archive/2008/11/22/nhibernate-schemavalidator.aspx">Here</a> you can find a short sample code showing how it works. </p>
<p>The class has got only one useful method called <strong>Validate()</strong>. It analyzes and compares database metadata with mappings. It can detect missing tables, missing columns, improper types in mappings, etc. It throws <strong>HibernateException</strong> immediately after it encounters such a problem. However, this is a serious disadvantage (at least for me), because I would like to know all issues related to my mappings and I don&#8217;t want to be surprised by a sudden NH exception telling me that I have forgotten one column in my .HBM file. That is why I have decided to reimplement this class so that it would not throw <strong>HibernateException</strong>, but rather return a list of possible issues.</p>
<p>The following code is based on original <strong>NHibernate.Tool.hbm2ddl.SchemaValidator</strong> class. Instead of throwing <strong>HibernateException</strong> it returns a list of strings. The code was tested with Sql Server 2005.</p>
<pre class="brush: csharp; title: ; notranslate">
using System;
using System.Collections.Generic;
using System.Data.Common;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Dialect.Schema;
using NHibernate.Engine;
using NHibernate.Id;
using NHibernate.Mapping;
using NHibernate.Tool.hbm2ddl;
using NHibernate.Util;

namespace MyApplication.Server.DAO.SchemaValidation
{
    class SchemaValidator
    {
        private readonly Configuration configuration;
        private readonly IConnectionHelper connectionHelper;
        private readonly Dialect dialect;

        public SchemaValidator(Configuration cfg) : this(cfg, cfg.Properties) { }

        public SchemaValidator(Configuration cfg, IDictionary&lt;string, string&gt; connectionProperties)
        {
            configuration = cfg;
            dialect = Dialect.GetDialect(connectionProperties);
            IDictionary&lt;string, string&gt; props = new Dictionary&lt;string, string&gt;(dialect.DefaultProperties);
            foreach (var prop in connectionProperties)
            {
                props[prop.Key] = prop.Value;
            }
            connectionHelper = new ManagedProviderConnectionHelper(props);
        }

        public SchemaValidator(Configuration cfg, Settings settings)
        {
            configuration = cfg;
            dialect = settings.Dialect;
            connectionHelper = new SuppliedConnectionProviderConnectionHelper(settings.ConnectionProvider);
        }

        public IList&lt;string&gt; Validate()
        {
            try
            {
                DatabaseMetadata meta;
                try
                {
                    connectionHelper.Prepare();
                    DbConnection connection = connectionHelper.Connection;
                    meta = new DatabaseMetadata(connection, dialect, false);
                }
                catch (Exception sqle)
                {
                    throw;
                }

                return ValidateSchema(dialect, meta);
            }
            catch (Exception e)
            {
                throw;
            }
            finally
            {
                try
                {
                    connectionHelper.Release();
                }
                catch (Exception e)
                {
                	throw;
                }
            }
        }

        private IList&lt;string&gt; ValidateSchema(
            Dialect dialect, DatabaseMetadata databaseMetadata)
        {
            IList&lt;string&gt; problems = new List&lt;string&gt;();

            string defaultCatalog = PropertiesHelper.GetString(NHibernate.Cfg.Environment.DefaultCatalog,
                configuration.Properties, null);
            string defaultSchema = PropertiesHelper.GetString(NHibernate.Cfg.Environment.DefaultSchema,
                configuration.Properties, null);

            IMapping mapping = configuration.BuildMapping();
            ICollection&lt;PersistentClass&gt; list = configuration.ClassMappings;
            foreach (PersistentClass pc in list)
            {
                try
                {
                    var table = pc.Table;
                    if (table.IsPhysicalTable)
                    {
                        ITableMetadata tableInfo = databaseMetadata.GetTableMetadata(
                            table.Name,
                            table.Schema ?? defaultSchema,
                            table.Catalog ?? defaultCatalog,
                            table.IsQuoted);
                        if (tableInfo == null)
                            problems.Add(string.Format(&quot;Missing table: {0}&quot;, table.Name));
                        else
                            ValidateColumns(problems, table, dialect, mapping, tableInfo);
                    }
                }
                catch (HibernateException ex)
                {
                    problems.Add(ex.Message);
                }
            }

            var persistenceIdentifierGenerators = IterateGenerators(dialect);
            foreach (var generator in persistenceIdentifierGenerators)
            {
                string key = generator.GeneratorKey();
                if (!databaseMetadata.IsSequence(key) &amp;&amp; !databaseMetadata.IsTable(key))
                {
                    problems.Add(string.Format(&quot;Missing sequence or table: {0}&quot;, key));
                }
            }
            return problems;
        }

        private IEnumerable&lt;IPersistentIdentifierGenerator&gt; IterateGenerators(Dialect dialect)
        {
            var generators = new Dictionary&lt;string, IPersistentIdentifierGenerator&gt;();
            string defaultCatalog = PropertiesHelper.GetString(NHibernate.Cfg.Environment.DefaultCatalog,
                configuration.Properties, null);
            string defaultSchema = PropertiesHelper.GetString(NHibernate.Cfg.Environment.DefaultSchema,
                configuration.Properties, null);

            foreach (var pc in configuration.ClassMappings)
            {
                if (!pc.IsInherited)
                {
                    var ig =
                        pc.Identifier.CreateIdentifierGenerator(dialect, defaultCatalog, defaultSchema, (RootClass)pc) as
                        IPersistentIdentifierGenerator;

                    if (ig != null)
                    {
                        generators[ig.GeneratorKey()] = ig;
                    }
                }
            }

            foreach (var collection in configuration.CollectionMappings)
            {
                if (collection.IsIdentified)
                {
                    var ig =
                        ((IdentifierCollection)collection).Identifier.CreateIdentifierGenerator(dialect, defaultCatalog, defaultSchema,
                                                                                                 null) as IPersistentIdentifierGenerator;

                    if (ig != null)
                    {
                        generators[ig.GeneratorKey()] = ig;
                    }
                }
            }

            return generators.Values;
        }

        private void ValidateColumns(
            IList&lt;string&gt; problems,
            Table table,
            Dialect dialect,
            IMapping mapping,
            ITableMetadata tableInfo)
        {
            IEnumerable&lt;Column&gt; iter = table.ColumnIterator;
            foreach (Column column in iter)
            {
                IColumnMetadata columnInfo = tableInfo.GetColumnMetadata(column.Name);

                if (columnInfo == null)
                {
                    problems.Add(string.Format(&quot;Missing column: {0} in {1}&quot;, column.Name,
                        NHibernate.Mapping.Table.Qualify(tableInfo.Catalog, tableInfo.Schema, tableInfo.Name)));
                }
                else
                {
                    bool typesMatch = column.GetSqlType(dialect, mapping).ToLower().StartsWith(columnInfo.TypeName.ToLower());
                    if (!typesMatch)
                    {
                        problems.Add(string.Format(&quot;Wrong column type in {0} for column {1}. Found: {2}, Expected {3}&quot;,
                                                                   NHibernate.Mapping.Table.Qualify(tableInfo.Catalog, tableInfo.Schema, tableInfo.Name),
                                                                   column.Name, columnInfo.TypeName.ToLower(),
                                                                   column.GetSqlType(dialect, mapping)));
                    }
                }
            }
        }

    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://lukaszbaran.com/blog/?feed=rss2&#038;p=216</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Visual Studio Design Mode &#8211; another approach.</title>
		<link>http://lukaszbaran.com/blog/?p=205</link>
		<comments>http://lukaszbaran.com/blog/?p=205#comments</comments>
		<pubDate>Sun, 20 Dec 2009 12:28:32 +0000</pubDate>
		<dc:creator>lukaszb</dc:creator>
				<category><![CDATA[Hints]]></category>
		<category><![CDATA[tips & tricks]]></category>
		<category><![CDATA[vs designer]]></category>
		<category><![CDATA[vs net 2008]]></category>

		<guid isPermaLink="false">http://lukaszbaran.com/blog/?p=205</guid>
		<description><![CDATA[Some time ago I published here a piece of code that detects the design mode in Visual Studio Designer. The code worked great (as long as you use only MS Visual Studio). However, after some time, with our project getting more and more complex, the solution turned out to be problematic, as its usage is [...]]]></description>
			<content:encoded><![CDATA[<p>Some time ago I published here <a href="http://lukaszbaran.com/blog/?p=138">a piece of code</a> that detects the design mode in Visual Studio Designer. The code worked great (as long as you use only MS Visual Studio). However, after some time, with our project getting more and more complex, the solution turned out to be problematic, as its usage is limited only to classes that extend the BaseDesignModeUserControl. If, for instance, you need to extend <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.component.aspx">System.ComponentModel.Component</a>, then you have to duplicate the code (and the rhetorical question is <em>who likes to duplicate the code?</em>)<br />
So, it turns out that we should forget about &#8220;the-base-class&#8221; approach and use an extension method instead:</p>
<pre class="brush: csharp; title: ; notranslate">
    public static class ExtensionMethods
    {
        private static bool? isDesignMode = null;

        [DebuggerStepThrough]
        public static bool IsDesignMode(this object obj)
        {
            if (!isDesignMode.HasValue)
                isDesignMode = (System.Diagnostics.Process.GetCurrentProcess().ProcessName.IndexOf(&quot;devenv&quot;) != -1);
            return isDesignMode.Value;
        }
    }
</pre>
<p>It seems that this piece of code may be called anywhere and I hope that this is the final solution of the problem. </p>
]]></content:encoded>
			<wfw:commentRss>http://lukaszbaran.com/blog/?feed=rss2&#038;p=205</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

