<?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>IN MY OPINION &#187; Programming</title>
	<atom:link href="http://blog.gomilko.com/category/programming/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.gomilko.com</link>
	<description>Andrew Gomilko's Blog</description>
	<lastBuildDate>Mon, 14 Jan 2008 08:09:19 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>YUI Compression tool as Ant Task</title>
		<link>http://blog.gomilko.com/2007/11/29/yui-compression-tool-as-ant-task</link>
		<comments>http://blog.gomilko.com/2007/11/29/yui-compression-tool-as-ant-task#comments</comments>
		<pubDate>Thu, 29 Nov 2007 18:45:52 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.gomilko.com/2007/11/29/yui-compression-tool-as-ant-task/</guid>
		<description><![CDATA[Minification over obfuscation and other uglifier techniques
Every mature web application enters phase when you need to optimize overall performance. Unfortunately, choosing right DB, tuning your SQL queries and using sophisticated load-balancers are not enough if a user&#8217;s browser have to wait for a 5 seconds to load your overloaded AJAX-based grid. And if it happens, [...]]]></description>
			<content:encoded><![CDATA[<h2>Minification over obfuscation and other uglifier techniques</h2>
<p>Every mature web application enters phase when you need to optimize overall performance. Unfortunately, choosing right DB, tuning your SQL queries and using sophisticated load-balancers are not enough if a user&#8217;s browser have to wait for a 5 seconds to load your overloaded AJAX-based grid. And if it happens, you have to think a lot and try many client-side optimization solutions. Now, developers have a great analyzing <a href="http://developer.yahoo.com/yslow/">YSlow</a> tool which can give you dozens of improvement tips. Actually, you can do all this work just analyzing response headers and content with another excellent tool &#8211; <a href="http://www.getfirebug.com/">Firebug</a>.</p>
<p>So, when our <a href="http://sonopia.com">application</a> had been optimized against almost all <a href="http://developer.yahoo.com/performance/rules.html">possible bottlenecks</a>, it was decided to use a sort of compression (apart from gzip, which is already employed) of resource files (js, css) based on its structure.</p>
<p>After a little comparison and talks with DHTML gurus, I chose using <a href="http://yuiblog.com/blog/2006/03/06/minification-v-obfuscation/">minification instead of obfuscation</a>, because the later one could be really source of evil bugs. Nowadays, the best supported minifier I found is <a href="http://developer.yahoo.com/yui/compressor/">YUI Compressor</a>. </p>
<h2>YUI Compressor</h2>
<p>I chose YUI Compressor because it is Java-based free open-sourced tool which means that I always can investigate why something goes wrong, and probable contribute something valuable. This tool can be used as a standalone command line application or used from your code instantiating necessary classes. It could parse javascript files as well as css. Also there is wide range of parameters (e.g. shorten local variables or not, preserve semicolons or not).</p>
<h2>Ant script</h2>
<p>Good overview of the tool usage from Ant script is <a href="http://www.julienlecomte.net/blog/2007/09/16/">here</a>. However, it is just calls to the compressor as to command-line program, which is verbose and sometimes not appropriate. Usually for such tools, there are custom Ant tasks. And it was obvious, that since sources of the tool is available, the Ant task should exist for the YUI Compressor too. After some googling, I found what I needed &#8211; semi-abandoned page <a href="http://www.ubik-ingenierie.com/ubikwiki/index.php?title=Minifying_JS/CSS">Minifying JS/CSS</a>. Many thanks to the author &#8211; Philippe Mouawad, well done! I would like to see this patch in the release and reference on the official site.</p>
<p>Simple example of usage:</p>
<div class="dean_ch" style="white-space: wrap;">
<p>&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;path</span> <span class="re0">id</span>=<span class="st0">&quot;yuicompressor.classpath&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;fileset</span> <span class="re0">dir</span>=<span class="st0">&quot;${yuicompressor.dir}&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;include</span> <span class="re0">name</span>=<span class="st0">&quot;**/yuicompressor-2.2.5.jar&quot;</span><span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;include</span> <span class="re0">name</span>=<span class="st0">&quot;**/YUIAnt.jar&quot;</span><span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="coMULTI">&lt;!&#8211; include name=&quot;**/rhino*.jar&quot;/ &#8211;&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/fileset<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/path<span class="re2">&gt;</span></span></span>&nbsp;</p>
<p>&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;minify-js-css&quot;</span> <span class="re0">description</span>=<span class="st0">&quot;Minifiy a set of files&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;taskdef</span> <span class="re0">name</span>=<span class="st0">&quot;yuicompress&quot;</span> <span class="re0">classname</span>=<span class="st0">&quot;com.yahoo.platform.yui.compressor.YUICompressTask&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;classpath<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;path</span> <span class="re0">refid</span>=<span class="st0">&quot;yuicompressor.classpath&quot;</span><span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/classpath<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/taskdef<span class="re2">&gt;</span></span></span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;delete</span> <span class="re0">dir</span>=<span class="st0">&quot;${js-min.dir}&quot;</span><span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;mkdir</span> <span class="re0">dir</span>=<span class="st0">&quot;${js-min.dir}&quot;</span> <span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;yuicompress</span> <span class="re0">linebreak</span>=<span class="st0">&quot;300&quot;</span> <span class="re0">warn</span>=<span class="st0">&quot;false&quot;</span> <span class="re0">munge</span>=<span class="st0">&quot;yes&quot;</span> <span class="re0">preserveallsemicolons</span>=<span class="st0">&quot;true&quot;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">outputfolder</span>=<span class="st0">&quot;${js-min.dir}&quot;</span> <span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;fileset</span> <span class="re0">dir</span>=<span class="st0">&quot;${js.dir}&quot;</span> <span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;include</span> <span class="re0">name</span>=<span class="st0">&quot;**/*.js&quot;</span> <span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/fileset<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/yuicompress<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span><br />
&nbsp;</div>
<h2>Encountered problems</h2>
<p>Everything works fine except one malicious trouble, I was struggling with for a day. If Rhino (which is stated as dependency library)<br />
was included in task classpath, all returning characters &#8220;\n&#8221; was pasted as a new line, and an JS error occurred.</p>
<div class="dean_ch" style="white-space: wrap;">
var a = &quot;aaa\nbbb&quot;;<br />
// turns after minification into:<br />
var a = &quot;aaa<br />
bbb&quot;;<br />
&nbsp;</div>
<p>This bug was eliminated by removing Rhino jar from classpath.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gomilko.com/2007/11/29/yui-compression-tool-as-ant-task/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Moving to Eclipse Europa for J2EE programmer</title>
		<link>http://blog.gomilko.com/2007/07/10/moving-to-eclipse-europa-for-j2ee-programmer</link>
		<comments>http://blog.gomilko.com/2007/07/10/moving-to-eclipse-europa-for-j2ee-programmer#comments</comments>
		<pubDate>Tue, 10 Jul 2007 21:22:26 +0000</pubDate>
		<dc:creator>Andrew</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.gomilko.com/2007/07/10/moving-to-eclipse-europa-for-j2ee-programmer/</guid>
		<description><![CDATA[Europa release
With a short delay after Europa release announcement, I&#8217;ve moved to it. Thanks to the fact that Eclipse doesn&#8217;t require an installation process and can be just unzipped and run, the last few times I got the tuned Eclipse from my co-workers. Those distributions were well-tuned for J2EE development, with all necessary plugins, project [...]]]></description>
			<content:encoded><![CDATA[<h3>Europa release</h3>
<p>With a short delay after Europa release announcement, I&#8217;ve moved to it. Thanks to the fact that Eclipse doesn&#8217;t require an installation process and can be just unzipped and run, the last few times I got the tuned Eclipse from my co-workers. Those distributions were well-tuned for J2EE development, with all necessary plugins, project <a href="http://checkstyle.sourceforge.net/">checkstyles</a>, attached sources and so on. Seeing as this time nobody around me offered me such a favor, I did everything on my own.<br />
Actually, to develop a J2EE project, you need to install a dozen of plugins (depends on which frameworks are employed) in addition to the bare distribution, so it&#8217;s better to have a cheat sheet every time you start this Eclipse tuning campaign. Since I didn&#8217;t have such a plan, I used my current Eclipse 3.1 working set as an example.<br />
This time, I wrote some short notes during the installation process, and I&#8217;d like to share it here, to have something in the future to stick with.</p>
<h3>Download</h3>
<p>Firstly, you need to download an appropriate Eclipse distribution. However there is already a bundle for J2EE developer, I was interested in installing everything I want from the scratch. Therefore I went to <a href="http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a> and downloaded <strong>Eclipse Classic</strong> distribution for Windows (140 MB). It was extracted to C:\Java\eclipse3.3 directory where I store all Java stuff like IDEs, JDKs, etc. Then, as usually I wanted to create a custom shortcut with extended memory allocation for Eclipse, but suddenly noticed <strong>eclipse.ini</strong> file. To allow Eclipse allocation of more memory, just edit the <strong>eclipse.ini</strong> file (increase Xms and Xmx values):</p>
<div class="dean_ch" style="white-space: wrap;">
-showsplash<br />
org.eclipse.platform<br />
&#8211;launcher.XXMaxPermSize<br />
256m<br />
-vmargs<br />
-Xms256m<br />
-Xmx512m<br />
&nbsp;</div>
<h3>Web tools</h3>
<p><em>Some general notes.</em> All plugins can be installed in two common ways: through cute <strong>Help->Software Updates->Find and Install&#8230;</strong> and copying all unzipped stuff to <strong>ECLIPSE_HOME/plugins</strong> directory. Of course I prefer the first option, and every plugin I&#8217;ll be installing through this wizard, except of Sysdeo.<br />
By &#8220;default plugins&#8221; I mean plugins which can be installed through &#8220;Europa Discovery Site&#8221; (run the mentioned wizard and find it to be accustomed, if not yet).</p>
<p>From the past experience I knew that I was using a <a href="http://www.eclipse.org/webtools">WTP</a> (stands for Web Tools Platform) plugin for web development. The problem was that there were no mentioned WTP plugin on the &#8220;Europa Discovery Site&#8221;. I carried brief investigation and dig out that the main part of that plugin is a <a href="http://www.eclipse.org/webtools/wst/main.php">WST</a> subproject (the web standard tools subproject).<br />
Steps to reproduce after <strong>Help->Software Updates->Find and Install&#8230;</strong>:<br />
<img src="http://gallery.gomilko.com/d/2452-1/WST.png" alt="WST plugin" /><br />
When I checked WST check box, the wizard apparently gave a tip to select all dependent (required by WST) things too. After I installed a WST, the link to WTP update site suddenly appeared (I guess that it was due to WST), and I decided to install it to have a full stack.<br />
<img src="http://gallery.gomilko.com/d/2459-1/WTP.png" alt="WTP plugin" /></p>
<h3>Subversion integration</h3>
<p>When I installed all useful tools from the Europa repository, I moved to things which update sites have to be added manually. The process is almost the same as when we were updating standard components, the only difference is the update site where the plugin is stored. We need to add http://subclipse.tigris.org/update_1.2.x as a <strong>New Remote Site&#8230;</strong><br />
<img src="http://gallery.gomilko.com/d/2457-1/updateManager.png" alt="Update manager" /></p>
<h3>Tomcat launcher</h3>
<p>The simplest and the most valuable plugin for Eclipse invoking I ever used is a <a href="http://www.eclipsetotale.com/tomcatPlugin.html">Sysdeo</a> Tomcat launcher. Download the archive and install according to Installation section steps. Here, the unzipped archive should be placed manually to the <strong>ECLIPSE_HOME/plugins</strong> directory.<br />
<img src="http://gallery.gomilko.com/d/2455-1/sysdeoButtons.png" alt="Sysdeo butons" /></p>
<h3>Useful tools</h3>
<p>As you know how to install plugins, I&#8217;ll mention only links to update site:</p>
<ol>
<li><a href="http://eclipse-cs.sourceforge.net/update">http://eclipse-cs.sourceforge.net/update</a> &#8211; checkstyle plugin, helps to maintain your coding style due to different available code conventions (Sun, Eclipse, your own)
</li>
<li>
<a href="http://springide.org/updatesite/SpringIDE">http://springide.org/updatesite/SpringIDE</a> &#8211; Spring related things like bean definitions, xml configuration auto completion
</li>
<li>
<a href="http://e-p-i-c.sf.net/updates">http://e-p-i-c.sf.net/updates</a> &#8211; Perl IDE, just for fun to play with RegExps or to write some admin tools
</li>
<li>
<a href="http://www.fabioz.com/pydev/updates">http://www.fabioz.com/pydev/updates</a> &#8211; PyDev (Python IDE) not to be restricted only by Java world and be more broadminded
</li>
<li>
<a href="http://eclipse-tools.sourceforge.net/implementors/">http://eclipse-tools.sourceforge.net/implementors/</a> &#8211; nice Alt+F3 short key usage, allows quick jumps to implementation from interfaces.
</li>
</ol>
<p>Stay tuned!<br />
P.S. I know that saying this phrase is almost as popular as mentioning iPhone in the blog post <img src='http://blog.gomilko.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gomilko.com/2007/07/10/moving-to-eclipse-europa-for-j2ee-programmer/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Natural order for strings with numbers in Java</title>
		<link>http://blog.gomilko.com/2007/05/31/natural-order-for-strings-with-numbers-in-java</link>
		<comments>http://blog.gomilko.com/2007/05/31/natural-order-for-strings-with-numbers-in-java#comments</comments>
		<pubDate>Thu, 31 May 2007 13:29:12 +0000</pubDate>
		<dc:creator>Andrew</dc:creator>
				<category><![CDATA[Code snippets]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.gomilko.com/2007/05/31/natural-order-for-strings-with-numbers-in-java/</guid>
		<description><![CDATA[File names default sort order
If you are developing an application which works with files, one day you&#8217;ll try to get list of the names of all files in a particular directory. It could be like this simplified snippet:

&#160; &#160; public List&#60;String&#62; getAllImageNames&#40;&#41; &#123;
&#160; &#160; &#160; &#160; List&#60;String&#62; names = new ArrayList&#60;String&#62;&#40;&#41;;
&#160; &#160; &#160; &#160; File [...]]]></description>
			<content:encoded><![CDATA[<h2>File names default sort order</h2>
<p>If you are developing an application which works with files, one day you&#8217;ll try to get list of the names of all files in a particular directory. It could be like this simplified snippet:</p>
<div class="dean_ch" style="white-space: wrap;">
<p>&nbsp; &nbsp; <span class="kw2">public</span> List&lt;String&gt; getAllImageNames<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; List&lt;String&gt; names = <span class="kw2">new</span> ArrayList&lt;String&gt;<span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AFile+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">File</span></a> imagesDir = <span class="kw2">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AFile+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">File</span></a><span class="br0">&#40;</span>IMAGE_BASE_DIRECTORY<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!imagesDir.<span class="me1">exists</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">return</span> names;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AFile+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">File</span></a> image : imagesDir.<span class="me1">listFiles</span><span class="br0">&#40;</span>COMMON_IMG_FILTER<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; names.<span class="me1">add</span><span class="br0">&#40;</span>image.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">return</span> names;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; &nbsp; <span class="kw2">private</span> <span class="kw2">static</span> <span class="kw2">final</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AFileFilter+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">FileFilter</span></a> COMMON_IMG_FILTER = <span class="kw2">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AFileFilter+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">FileFilter</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">boolean</span> accept<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AFile+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">File</span></a> pathname<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">return</span> pathname.<span class="me1">isFile</span><span class="br0">&#40;</span><span class="br0">&#41;</span> &amp;&amp; <span class="br0">&#40;</span>!pathname.<span class="me1">getName</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">startsWith</span><span class="br0">&#40;</span><span class="st0">&quot;.&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span>;<br />
&nbsp;</div>
<p>Let&#8217;s assume that you have some image files with the same name suffix and an index number as a trailing part:</p>
<table>
<tr>
<th>System order</th>
<th>Natural order</th>
<tr>
<tr>
<td>IMG_1.jpg</td>
<td>IMG_1.jpg</td>
<tr>
<tr>
<td>IMG_2.jpg</td>
<td>IMG_2.jpg</td>
<tr>
<tr>
<td>IMG_21.jpg</td>
<td>IMG_3.jpg</td>
<tr>
<tr>
<td>IMG_22.jpg</td>
<td>IMG_21.jpg</td>
<tr>
<tr>
<td>IMG_3.jpg</td>
<td>IMG_22.jpg</td>
<tr>
</table>
<p>Everything seems to be all right, but returned list is sorted in a way Java usually sorts strings. While this results could completely satisfy your program API, it is not very useful to work with such lists for a human. Moreover, such lists are very common in our life, for example, many digital photo cameras store pictures with such names.<br />
Let&#8217;s make the problem more general. We have a list of strings, which could contain digits, and we want to sort this array to get a natural ordered list. You&#8217;d say that it is piece of cake, because Java has good facility to perform array/list sorting : <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collections.html#sort(java.util.List,%20java.util.Comparator)">Collections.sort()</a> and <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Comparator.html">Comparator</a>. Therefore, we need an appropriate <code>Comparator</code> implementation.</p>
<h2>Known solutions for natural order sorting</h2>
<p>Unfortunately, there are no any well-known library like <a href="http://jakarta.apache.org/commons/">Jakarta Commons</a> to perform this sort. And if you try to google it, you will find only some posts like this one with home-grown solutions and grumbling about lack of existing proven solution. The most important thing is to know the right keywords to google against it. Most of articles on this topic are about <a href="http://www.google.com/search?hl=uk&#038;q=Natural+order&#038;btnG=%D0%9F%D0%BE%D1%88%D1%83%D0%BA+Google&#038;meta=">Natural order</a>. </p>
<p>I found some valuable resources:</p>
<ul>
<li><a href="http://weblogs.java.net/blog/skelvin/archive/2006/01/natural_string.html">Natural String Order</a> at Stephen Friedrich&#8217;s Blog &#8211; an article of Java professional with working Java <a href="http://www.eekboom.com/java/compareNatural/src/com/eekboom/utils/Strings.java">source</a> and even JUnit <a href="http://www.eekboom.com/java/compareNatural/src_test/com/eekboom/utils/TestStrings.java">tests</a>. The implemented algorithm is very comprehensive and can work with different set of sorting rules (Ascii, case insensitive and locale specific).</li>
<li><a href="http://jroller.com/page/tfenne/?anchor=humanestringcomparator_sorting_strings_for_people">HumaneStringComparator: Sorting Strings for People</a> &#8211; another one <em>Comparator</em> implementation by Tim Fennell.</li>
<li><a href="http://pierre-luc.paour.9online.fr/NaturalOrderComparator.java">Implementation</a> by Pierre-Luc Paour.</li>
<li><a href="http://sourcefrog.net/projects/natsort/">Natural Order String Comparison</a> &#8211; C version of implementation and links to another languages.</li>
<li><a href="http://www.naturalordersort.org/">Natural Order Numerical Sorting</a> &#8211; overview of the problem, links to another articles and solutions, but almost all of them are broken or not Java. It seemed that the author was keen about that idea, registered a special domain and gathered essential information, and then left this site floating without any maintain.</li>
</ul>
<h2>Stress test</h2>
<p>One of the main software development rule states: don&#8217;t invent your own wheel unless the problem is not your core business. As string sorting was a utility purpose matter, before implementing my own solution I decided to test already found. The test was easy and straightforward &#8211; every <em>Comparator</em> had to sort the same number of randomly generated and shuffled strings. The strings were generated by fixed pattern: <code>[a-z][0..1000].jpg</code>. Input data was the large array (100000) of such strings:<br />
<code>..............<br />
jqazrrveqy113.jpg<br />
wzedsgzmvo912.jpg<br />
aayexqpfdu311.jpg<br />
zvpzxjwkml354.jpg<br />
nelacribtl964.jpg<br />
rehsgmzugb244.jpg<br />
eoptzxybtz459.jpg<br />
ukbeogpmhe157.jpg<br />
zgvnrzohwc176.jpg<br />
.............. .<br />
</code><br />
I was interested in only one algorithm efficiency parameter &#8211; time elapsing during full sort. As usual, the elapsing time itself doesn&#8217;t tell much about the efficiency. To have a minimum achievable value to compare with I chose a result given by the comparator based on a standard Java <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html#compareTo(java.lang.String)">String.compareTo()</a> method which should be the fastest because it doesn&#8217;t deal with string parsing.</p>
<div class="dean_ch" style="white-space: wrap;">
&nbsp; &nbsp; &nbsp; &nbsp; Comparator&lt;String&gt; baseComparator = <span class="kw2">new</span> Comparator&lt;String&gt;<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">int</span> compare<span class="br0">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AString+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">String</span></a> strA, <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AString+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span class="kw3">String</span></a> strB<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Assuming that strA always != null</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">return</span> strA.<span class="me1">compareTo</span><span class="br0">&#40;</span>strB<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;<br />
&nbsp;</div>
<p>The test results are shown in a table:</p>
<table>
<tr>
<th>Author
<th>
<th>Version</th>
<th>Sort Time</th>
<th>Pros</th>
<th>Cons</th>
</tr>
<tr>
<td>Pierre-Luc Paour
<td>
<td><a href="http://pierre-luc.paour.9online.fr/NaturalOrderComparator.java">NaturalOrderComparator</a></td>
<td>453ms</td>
<td>Quite fast</td>
<td>hard to read C-style algorithm</td>
</tr>
<tr>
<td>Stephen Friedrich
<td>
<td><a href="http://weblogs.java.net/blog/skelvin/archive/2006/01/natural_string.html">NaturalComparator</a></td>
<td>4828ms</td>
<td>Locale specific</td>
<td>Too slow</td>
</tr>
<tr>
<td>Stephen Friedrich
<td>
<td><a href="http://weblogs.java.net/blog/skelvin/archive/2006/01/natural_string.html">NaturalComparatorAscii</a></td>
<td>360ms</td>
<td>The fastest one</td>
<td>Only ASCII</td>
</tr>
<tr>
<td>Stephen Friedrich
<td>
<td><a href="http://weblogs.java.net/blog/skelvin/archive/2006/01/natural_string.html">NaturalComparatorIgnoreCaseAscii</a></td>
<td>500ms</td>
<td>Fast enough, case insensitive</td>
<td>Only ASCII</td>
</tr>
<tr>
<td>Tim Fennell
<td>
<td><a href="http://jroller.com/page/tfenne/?anchor=humanestringcomparator_sorting_strings_for_people">HumaneStringComparator </a></td>
<td>4797ms</td>
<td>Very good example of OOP style, brief understandable algorithm, use Java facilities extensively</td>
<td>Too slow and inefficient</td>
</tr>
<tr>
<td>Java native
<td>
<td>String.compareTo()</td>
<td>235ms</td>
<td>standard</td>
<td>standard</td>
</tr>
</table>
<h2>Conclusion</h2>
<p>As you can see from the result sheet, the most powerful and fast is Stephen Friedrich&#8217;s package. It is written with good Java style, well commented and supplied with JUnit tests. It provides different kind of sorting depends on what are going to sort &#8211; simple ASCII strings like file names or country specific strings containing special characters.<br />
Of course, one day I&#8217;d like to see any well-proven solution in the <a href="http://jakarta.apache.org/commons/">Jakarta Commons</a> project and simply add it as a jar.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gomilko.com/2007/05/31/natural-order-for-strings-with-numbers-in-java/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Wordpress theme redesigned</title>
		<link>http://blog.gomilko.com/2007/05/28/wordpress-theme-redesigned</link>
		<comments>http://blog.gomilko.com/2007/05/28/wordpress-theme-redesigned#comments</comments>
		<pubDate>Mon, 28 May 2007 18:41:32 +0000</pubDate>
		<dc:creator>Andrew</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Social]]></category>

		<guid isPermaLink="false">http://blog.gomilko.com/2007/05/28/wordpress-theme-redesigned/</guid>
		<description><![CDATA[As I stated a few days ago, I mistakenly broke my previously used FastTrack theme. I liked it very much because of the main photo at the top. There depicted a young men with a rucksack walking along underground station. As his face was hidden and his picture was blurred, his character resembled me. I [...]]]></description>
			<content:encoded><![CDATA[<p>As I stated a few days ago, I mistakenly <a href="/2007/05/24/broken-blog/">broke </a>my previously used <a href="http://wpthemes.info/fast-track/">FastTrack</a> theme. I liked it very much because of the main photo at the top. There depicted a young men with a rucksack walking along underground station. As his face was hidden and his picture was blurred, his character resembled me. I like wearing rucksacks and usually use subway if I need to get somewhere. This fact made the theme quite personal, and I didn&#8217;t need to customize it more for a long time. After I broke the theme and I had some hours to get down to <a href="http://codex.wordpress.org/Using_Themes">WordPress Themes</a> internal kitchen, I created my own theme.</p>
<p>To not take long, I&#8217;ll write my work log:</p>
<h3>WP Theme editing on the local machine</h3>
<p>Editing a WP theme remotely is a real pain. In this case, you have to upload/download your theme sources every time you change something. More easy way is a installing your WP copy on the local machine. There are lots of <a href="http://urbangiraffe.com/2005/05/22/installing-wordpress-on-your-own-windows-computer/">howto-s</a> over the Internet. I&#8217;m little bit familiar with Apache+PHP+MySQL bundle, and installed it within 30 minutes. After this, I downloaded my current WP files from my hosting directory and upgraded it <a href="http://wordpress.org/download/">the latest WP version</a> (2.2).</p>
<h3>Tools</h3>
<p>I took the FastTrack theme as a base for my new theme. The markup of all themes are very similar, because all of them uses the same layout: <em>header</em>, <em>content</em>, <em>sidebar</em> and <em>footer</em>. All parts are stored in few <em>.php</em> files with correspondent and clear names. The appearance of a theme is mostly determined by СSS file with styles of all parts. Hence almost all time you have to work with a CSS file editor. For this purpose I chose the great <a href="http://www.getfirebug.com/">FireBug Add-On</a> which show all comprehensive information about a web page including a CSS styles and HTML components on the page. PHP files I edited with <a href="http://www.activestate.com/products/komodo_ide/">Komodo</a> and CSS styles with <a href="http://www.newsgator.com/Individuals/TopStyle/">TopStyle</a>. For choosing right color schema I found out cool on-line tool for color schema generation &#8211; <a href="http://kuler.adobe.com/">kuler</a>.</p>
<h3>Creation</h3>
<p>I took one of my photos which looked fine as a header image and cropped it to the proper size. Then I tidied up all unnecessary elements like top navigation, odd styles, etc. The width of the post area became wider on 100px. Then I chose a color schema using <a href="http://kuler.adobe.com/">kuler</a>. It took some time to play with links appearance and font sizes. And in a few hours the new theme I called <em>harpsichord</em> was done.</p>
<p>If you want to customize your theme, I can suggest you starting from <a href="http://codex.wordpress.org/Using_Themes">Guides to creating your own themes</a>.</p>
<p>P.S.<br />
I eventually tasted the new-brand Eclipse chewing gum <img src='http://blog.gomilko.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  For those who are unfamiliar with <a href="/2007/04/23/eclipse-chewing-gum/">my special interest</a> to it, I&#8217;d say that Eclipse is the most popular open-sourced IDE for Java language (not only however).</p>
<div class="wpg2tag-image"><a href="http://blog.gomilko.com/wpg2?g2_itemId=2048" title="Eclipse chewing gum"><img src="http://gallery.gomilko.com/main.php?g2_view=core.DownloadItem&amp;g2_itemId=2049&amp;g2_serialNumber=2" width="150" height="113" id="IFid2" class="ImageFrame_None" alt="Eclipse chewing gum"/></a></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.gomilko.com/2007/05/28/wordpress-theme-redesigned/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
