<?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>techbits.de</title>
	<atom:link href="http://www.techbits.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.techbits.de</link>
	<description>thoughts on hardware, software, development and tech news</description>
	<lastBuildDate>Thu, 11 Feb 2010 21:37:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Recursive file iteration in Java</title>
		<link>http://www.techbits.de/2010/02/11/recursive-file-iteration-in-java/</link>
		<comments>http://www.techbits.de/2010/02/11/recursive-file-iteration-in-java/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 21:15:48 +0000</pubDate>
		<dc:creator>florian</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[apidesign]]></category>
		<category><![CDATA[bestpractice]]></category>

		<guid isPermaLink="false">http://www.techbits.de/?p=198</guid>
		<description><![CDATA[In a java frameworks talk I gave recently I showed the  following example for finding files recursively&#8230;

public void listFilesInDirectory(File dir) {
  File[] files = dir.listFiles();
  if (files != null) {
    for  (File f : files) {
      if (f.isDirectory()) {
        listFilesInDirectory(f);
      } else {
        System.out.println(f.getName());
      }
    }
  }
}

&#8230;  [...]]]></description>
			<content:encoded><![CDATA[<p>In a java frameworks talk I gave recently I showed the  following example for finding files recursively&#8230;</p>
<blockquote>
<pre><span style="font-family: Courier New;">public void listFilesInDirectory(File dir) {
  File[] files = dir.listFiles();
  if (files != null) {
    for  (File f : files) {
      if (f.isDirectory()) {
        listFilesInDirectory(f);
      } else {
        System.out.println(f.getName());
      }
    }
  }
}</span></pre>
</blockquote>
<p>&#8230;  which in real projects often grows to a larger block of code. The web is  full of code blocks like this for walking a directory tree. The best  version I came across is<a id="wylk" title="this object oriented one by Torsten  Curdt" href="http://vafer.org/blog/20071112204524"> this  object oriented one by Torsten Curdt</a>. Since you usually don&#8217;t want  to write this yourself, I suggested in my talk to use FileUtils which  makes recursive iteration much easier:</p>
<blockquote>
<pre>Collection jspFiles = FileUtils.listFiles(rootDirName,
                        new String[] { "jsp" }, true);</pre>
</blockquote>
<p>This looks concise and useful but as I tried to use it, I wasn&#8217;t too pleased with the FileUtils&#8217; solution. Here is why:</p>
<ul>
<li>The recursion is processed in one go, i.e. all  results are written to a List even when using the iterateFiles method.  The recursion is not processed iteratively.</li>
<li>You can not  influence the directories that are searched.</li>
<li>Only files are  returned, you can not search for directories.</li>
<li>The API is not  very expressive (e.g. what does the &#8220;true&#8221; mean).</li>
<li>No generics  (raw collection types are returned).</li>
</ul>
<h1>A Better API</h1>
<p>Not  being satisfied with the solutions I found, I &#8220;dreamed up&#8221; my own API  for listing and finding files. I don&#8217;t consider it complete but for the  most part I am pleased with the ease of use that the builder pattern  provides. The code for this can currently be found in an <a id="l6db" title="unrelated goole code project" href="http://code.google.com/p/data-integrity-check/source/browse/#svn/trunk/src/main/java/de/fmaul/common/io">unrelated goole code project</a>. The rest of this article  shows the functions that are currently supported.</p>
<h2>Find files two  ways</h2>
<p>There are generally two ways to use the result &#8211; as interator  or as list:</p>
<p><span style="font-family: Arial;">1. Iterate over all  files in the windows directory:</span></p>
<blockquote><p><span style="font-family: Courier New;">for (File f : <strong>Files.find</strong>(&#8221;c:\\windows&#8221;))  {</span><br style="font-family: Courier New;" /><br style="font-family: Courier New;" /><span style="font-family: Courier New;">}</span></p></blockquote>
<p>2.  Get all the files in a directory as a list of files:</p>
<blockquote><p><span style="font-family: Courier New;">List&lt;File&gt; allFiles = <strong>Files.find</strong>(somedir).<strong>list()</strong>;</span></p></blockquote>
<p><span style="font-family: Verdana;">Except from the return type the second  version does the same </span><span style="font-family: Courier New;"><span style="font-family: Verdana;">as the JDK command listFiles:</span></span></p>
<blockquote>
<pre>File[]  allFiles = (new File(somedir)).listFiles()</pre>
</blockquote>
<h2>Easy  recursive listing</h2>
<p>To iterate all the files in the C:\Windows  directory, you would use:</p>
<blockquote><p><span style="font-family: Courier New;">for  (File f : Files.find(&#8221;c:\\windows&#8221;).<strong>recursive()</strong>) {</span><br style="font-family: Courier New;" /><br style="font-family: Courier New;" /><span style="font-family: Courier New;">}</span></p></blockquote>
<p>Note: This actually  works iteratively, i.e. the recursion happens as you fetch files from  the iterator. The result is not fetched into a huge list.</p>
<p>With a  Predicate you can limit the recursion to specific directories. In this  example all .svn directories within a source tree are skipped:</p>
<blockquote><p><span style="font-family: Courier New;">Predicate&lt;File&gt; noSvnDirs = new Predicate&lt;File&gt;() {</span><br style="font-family: Courier New;" /><span style="font-family: Courier New;"> boolean apply(File file) {</span><br style="font-family: Courier New;" /><span style="font-family: Courier New;"> return  !file.getName().equals(&#8221;.svn&#8221;);</span><br style="font-family: Courier New;" /><span style="font-family: Courier New;"> }</span><br style="font-family: Courier New;" /><span style="font-family: Courier New;">}</span></p>
<p><span style="font-family: Courier New;">for (File f  : Files.find(&#8221;src/java/&#8221;).<strong>recursive(noSvnDir)</strong>) {</span><br style="font-family: Courier New;" /><span style="font-family: Courier New;"> </span><br style="font-family: Courier New;" /><span style="font-family: Courier New;">}</span></p></blockquote>
<h2>Want Files,  Directories or both?</h2>
<p>Define if you want only files, only directories  or both in your result with yield*()-Methods.</p>
<blockquote>
<pre>Files.find(someBaseDir).recursive().yieldFiles()  // this is the default
Files.find(someBaseDir).recursive().yieldDirectories()
Files.find(someBaseDir).recursive().yieldFilesAndDirectories()</pre>
</blockquote>
<h2>Filtering  the results</h2>
<p>To get all textfiles within a dir use:</p>
<blockquote>
<pre>Files.find(dir).withExtension("txt").list();
Files.find(dir).ignoreCase().withExtension("txt").list();</pre>
</blockquote>
<p>You  can also filter by Name, e.g. to find README files:</p>
<blockquote>
<pre>Files.find(dir).withName("README").list();
Files.find(dir).ignoreCase().withName("readme").list();</pre>
</blockquote>
<p>Note  that the default matching is case sensitive. The commands  caseSensitive() and ignoreCase() can be used to toggle the matching  behaviour.</p>
<p>For special needs you can also specify a  Predicate&lt;File&gt; to filter the resulting files.</p>
<blockquote>
<pre>Files.find(dir).recursive().withFilter(somePredicate).list();</pre>
</blockquote>
<h2>Finding  Directories</h2>
<p>When looking for directories there are some special  usecases that are supported, e.g. looking for directories that contain a  specific file:</p>
<blockquote>
<pre>Files.find(dir).recursive().yieldDirectories()
               .containingFile("Thumbs.db");</pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.techbits.de/2010/02/11/recursive-file-iteration-in-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android exploration continued</title>
		<link>http://www.techbits.de/2010/01/04/android-exploration-continued/</link>
		<comments>http://www.techbits.de/2010/01/04/android-exploration-continued/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 12:01:13 +0000</pubDate>
		<dc:creator>florian</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.techbits.de/?p=192</guid>
		<description><![CDATA[I extended my android application with a preferences screen now, which is quite easy to do.

A tutorial for creating a Preferences Activity got me started &#8211; unfortunaltely the xml preferences definition it uses is incorrect. The tags are names of Classes which have to be capitalized.
The open the preferences activity I added a Option Menu.
I [...]]]></description>
			<content:encoded><![CDATA[<p>I extended my android application with a preferences screen now, which is quite easy to do.</p>
<ul>
<li>A <a href="http://www.androidguys.com/2008/09/29/whats-your-preference-part-one/">tutorial for creating a Preferences Activity</a> got me started &#8211; unfortunaltely the xml preferences definition it uses is incorrect. The tags are names of Classes which have to be capitalized.</li>
<li>The open the preferences activity I added a <a href="http://developer.android.com/guide/topics/ui/menus.html">Option Menu</a>.</li>
<li>I wanted to add some kind of progress indicator. I ended up using the <a href="http://developer.android.com/reference/android/app/ProgressDialog.html">ProgressDialog </a>and the <a href="http://developer.android.com/reference/android/os/AsyncTask.html">AsyncTask </a>to run the downloading and xml parsing in the background. To fix issues with device rotation I might have a look at the BetterAsyncTask in the <a href="http://github.com/kaeppler/droid-fu">Droid-FU library</a> later.</li>
<li>I also ran into DateFormat and Date issues with the UTC formated Date in the XML file. I Thought about using <a href="http://joda-time.sourceforge.net/"> joda-time</a> at least twice but then stuck to the JDK implementation for smaller app size. The fact that android brings it&#8217;s own class named DateFormat which just provides a localized JDK-DateFormat object doesn&#8217;t help either.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.techbits.de/2010/01/04/android-exploration-continued/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>First Steps with Android</title>
		<link>http://www.techbits.de/2009/12/30/first-steps-with-android/</link>
		<comments>http://www.techbits.de/2009/12/30/first-steps-with-android/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 10:02:54 +0000</pubDate>
		<dc:creator>florian</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://www.techbits.de/?p=189</guid>
		<description><![CDATA[In the last few days I started out with some android development. Here are some things learned so far developing my first app:

The Android Tutorials are a great starting point, though i only followed through with the HelloWorld Tutorial. In retrospect I should have looked at the Notepad Tutorial a little closer because it explains [...]]]></description>
			<content:encoded><![CDATA[<p>In the last few days I started out with some android development. Here are some things learned so far developing my first app:</p>
<ul>
<li>The Android Tutorials are a great starting point, though i only followed through with the <a href="http://developer.android.com/intl/de/resources/tutorials/hello-world.html">HelloWorld</a> Tutorial. In retrospect I should have looked at the <a href="http://developer.android.com/intl/de/resources/tutorials/notepad/index.html">Notepad Tutorial</a> a little closer because it explains important concepts (namely activities/intents).</li>
<li><a href="http://www.anddev.org/">http://www.anddev.org/</a> is a useful source for tutorials and code snippets</li>
<li>It&#8217;s still java but a completely different API, so you often have to look for classes and methods via code completion oder in examples to get things done.</li>
<li><strong>Downloading:</strong> Can be done with the included HTTP Client library. Unfortuantely <a href="http://dlinsin.blogspot.com/2009/08/http-basic-authentication-with-android.html">Android still uses an old version of the HTTP Client</a> though, which made it hard to find documentation (e.g. how to set authentication credentials). Additionally you shoudn&#8217;t forget to declare the INTERNET-permissions in your application manifest.</li>
<li><strong>Storing and retrieving Files</strong> looks fairly easy (getDir(), getCacheDir()-Methods are there) at first sight but you have to unerstand the Android filesystem security model if you don&#8217;t want to spend hours with debugging. The before mentoined methods use internal storage where each application stores it&#8217;s data independently. Public read/write (e.g. file exchange with other applications) is only possible when you store your content with the specific method openFileOutput(). The external SD card on the other hand can be openly accessed with the regular Java File API.</li>
<li><strong>XML Parsing:</strong> I started out with the sax parser but since my XML file was pretty complex I ditched it and downloaded<a href="http://brainflush.wordpress.com/2009/05/19/the-force-unleashed-xmlxpath-on-android-using-dom4j-and-jaxen/"> dom4j</a> which has a really easy to use API. Unfortunately it adds at least 200KB of final app size. I now realized I could have gone with the<a href="http://www.anddev.org/parse_xml_with_dom_-_getnodevalue_always_null-t3082.html"> regular DOM parser</a> which has a decent API. I&#8217;ll have to reevaluate this later &#8211; maybe the end user responsiveness does require the faster streaming parser approach (sax).</li>
<li><strong>UI design:</strong> Declarative XML based looks powerful and well thought out but I mostly stuck to tutorial layout for now. This is an area I still have to get into.</li>
</ul>
<p>Ok, that&#8217;s it for now. Android is turning out to be a great plattform &#8211; exciting times.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techbits.de/2009/12/30/first-steps-with-android/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding Googles GData Java API to your maven repository</title>
		<link>http://www.techbits.de/2009/08/06/adding-googles-gdata-java-api-to-your-maven-repository/</link>
		<comments>http://www.techbits.de/2009/08/06/adding-googles-gdata-java-api-to-your-maven-repository/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 17:09:34 +0000</pubDate>
		<dc:creator>florian</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[gdata]]></category>
		<category><![CDATA[install]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[mavenize]]></category>
		<category><![CDATA[mvn]]></category>

		<guid isPermaLink="false">http://www.techbits.de/?p=181</guid>
		<description><![CDATA[The google gdata apis do not come with maven POM-files. Someone went through the trouble to &#8220;mavenize&#8221; the source but it is limited to linux as build plattform and currently out of date (compile errors). So I installed the JARs from the binary distribution of the APIs into my local repository &#8211; which are of [...]]]></description>
			<content:encoded><![CDATA[<p>The<a href="http://code.google.com/intl/de-DE/apis/gdata/overview.html"> google gdata apis</a> do not come with maven POM-files. Someone went through the trouble to <a href="http://code.google.com/p/google-apis-mavenized/">&#8220;mavenize&#8221; the source</a> but it is limited to linux as build plattform and currently out of date (compile errors). So I installed the JARs from the binary distribution of the APIs into my local repository &#8211; which are of course missing the dependencies between the individual JAR files. Here are two batch files which I used to install the JARs quite painlessly:</p>
<p>install.bat:</p>
<blockquote>
<pre>@SET mvn=d:\java\maven\bin\mvn
@%mvn% install:install-file -DgroupId=com.google.gdata
       -DartifactId=%1 -Dversion=%2 -Dfile=%3 -Dpackaging=jar
       -DgeneratePom=true</pre>
</blockquote>
<p>installall.bat:</p>
<blockquote>
<pre>call install.bat gdata-analytics 2.0 gdata-analytics-2.0.jar
call install.bat gdata-appsforyourdomain 1.0 gdata-appsforyourdomain-1.0.jar
call install.bat gdata-base 1.0 gdata-base-1.0.jar
call install.bat gdata-blogger 2.0 gdata-blogger-2.0.jar
call install.bat gdata-books 1.0 gdata-books-1.0.jar
call install.bat gdata-calendar 1.0 gdata-calendar-2.0.jar
call install.bat gdata-client 1.0 gdata-client-1.0.jar
call install.bat gdata-codesearch 2.0 gdata-codesearch-2.0.jar
call install.bat gdata-contacts 3.0 gdata-contacts-3.0.jar
call install.bat gdata-core 1.0 gdata-core-1.0.jar
call install.bat gdata-docs 2.0 gdata-docs-2.0.jar
call install.bat gdata-finance 2.0 gdata-finance-2.0.jar
call install.bat gdata-health 2.0 gdata-health-2.0.jar
call install.bat gdata-maps 2.0 gdata-maps-2.0.jar
call install.bat gdata-media 1.0 gdata-media-1.0.jar
call install.bat gdata-photos 2.0 gdata-photos-2.0.jar
call install.bat gdata-spreadsheet 3.0 gdata-spreadsheet-3.0.jar
call install.bat gdata-webmastertools 2.0 gdata-webmastertools-2.0.jar
call install.bat gdata-youtube 2.0 gdata-youtube-2.0.jar</pre>
</blockquote>
<p>You surely could get fancy and automate the splitting between artifact-name and version number, but hey, I needed those JARs installed quickly and that&#8217;s what it does.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techbits.de/2009/08/06/adding-googles-gdata-java-api-to-your-maven-repository/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Splitting mp3/cue files into multiple mp3 files</title>
		<link>http://www.techbits.de/2009/07/26/splitting-mp3cue-files-into-multiple-mp3-files/</link>
		<comments>http://www.techbits.de/2009/07/26/splitting-mp3cue-files-into-multiple-mp3-files/#comments</comments>
		<pubDate>Sun, 26 Jul 2009 09:46:33 +0000</pubDate>
		<dc:creator>florian</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[cue]]></category>
		<category><![CDATA[mp3]]></category>
		<category><![CDATA[split]]></category>

		<guid isPermaLink="false">http://www.techbits.de/?p=179</guid>
		<description><![CDATA[Usually you encode single MP3 files for each track on a CD. But there are cases when it&#8217;s sensible to encode the whole CD as one MP3 file. This is usually done, when you have a continuos live album where you want to avoid gaps between the tracks und preserve the original timecodes of the CD. [...]]]></description>
			<content:encoded><![CDATA[<p>Usually you encode single MP3 files for each track on a CD. But there are cases when it&#8217;s sensible to encode the whole CD as one MP3 file. This is usually done, when you have a continuos live album where you want to avoid gaps between the tracks und preserve the original timecodes of the CD. In these cases you create a single MP3 file and a <a href="http://en.wikipedia.org/wiki/Cue_sheet_%28computing%29">CUE file</a> which contains the timecodes and track names for the single tracks in the MP3.</p>
<p>When you later like to split thes MP3/CUE files into individial MP3 files you need a specialized tool. Lately I used <a href="http://www.medieval.it/content/view/28/71/">Medieval CUE Splitter</a> to achieve this. It is a small freeware application which splits the MP3 and even fill the ID3-Tags from the information in the CUE files.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techbits.de/2009/07/26/splitting-mp3cue-files-into-multiple-mp3-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;Continue later&#8221; for filling out Google Docs Forms</title>
		<link>http://www.techbits.de/2009/07/23/continue-later-for-filling-out-google-docs-forms/</link>
		<comments>http://www.techbits.de/2009/07/23/continue-later-for-filling-out-google-docs-forms/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 17:03:02 +0000</pubDate>
		<dc:creator>florian</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[docs]]></category>
		<category><![CDATA[fillout]]></category>
		<category><![CDATA[forms]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[interrupt]]></category>
		<category><![CDATA[survey]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.techbits.de/?p=177</guid>
		<description><![CDATA[Google Docs/Spreadsheets forms can be used easily as a simple survey tool. You just have to send a link to the participants who have to fill out and submit the form. The only problem: The forms have to be filled out in one go, you can not come back later and continue editing the form. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://googledocs.blogspot.com/2008/02/stop-sharing-spreadsheets-start.html">Google Docs/Spreadsheets forms</a> can be used easily as a simple survey tool. You just have to send a link to the participants who have to fill out and submit the form. The only problem: The forms have to be filled out in one go, you can not come back later and continue editing the form. Of cause this is particularly bad when you a have a really long questionnaire.</p>
<p>On way to provide the &#8220;continue later&#8221; functionality is to use a tool that saves your web browser&#8217;s form state. <a href="https://addons.mozilla.org/de/firefox/addon/6984">Lazarus: Form Recovery</a> is one of those tools for Firefox that constantly saves the state of your web forms and allows you to load previous content when you return to a website. This works very well with Google Docs Forms. You can interrupt filling out the form at any time, return later and restore the information you previously entered with a few clicks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techbits.de/2009/07/23/continue-later-for-filling-out-google-docs-forms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IndexedList: A hybrid of a Java List and a Map</title>
		<link>http://www.techbits.de/2009/07/18/indexedlist-a-hybrid-of-a-java-list-and-a-map/</link>
		<comments>http://www.techbits.de/2009/07/18/indexedlist-a-hybrid-of-a-java-list-and-a-map/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 11:00:09 +0000</pubDate>
		<dc:creator>florian</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[collections]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.techbits.de/?p=164</guid>
		<description><![CDATA[If been working on legacy data import code in the last months with a lot of code searching for exisiting objects in lists. I realized I needed a different collection to speed up searching for identifiers and couldn&#8217;t find any standard collection that matches my needs. I basically need an index like Maps.uniqueIndex() from the [...]]]></description>
			<content:encoded><![CDATA[<p>If been working on legacy data import code in the last months with a lot of code searching for exisiting objects in lists. I realized I needed a different collection to speed up searching for identifiers and couldn&#8217;t find any standard collection that matches my needs. I basically need an index like <span style="font-family: Courier New;">Maps.uniqueIndex()</span> from the <a href="http://code.google.com/p/google-collections/">Google Collections Library</a> provides but it should be updating dynamically and not only be generated once.</p>
<p><span id="more-164"></span>To summarize my requirements:</p>
<ul>
<li>A List (ArrayList) which can be modified as usual</li>
<li>A way to find objects (contains and get) in constant time by a custom attribute (like a HashMap)</li>
<li>No reliance on equals() and hashcode() because they cover more attributes (an can not be changed)</li>
</ul>
<p>The <span style="font-family: Courier New;">LinkedHashMap </span>seems to almost fit the bill but it is not a true List and therefore not a great drop in replacement.</p>
<p>What I&#8217;m using right now is a wrapper around a List which maintains an additional HashMap to find objects by the index criterium. The index is automatically updated whenever the list is modified. This is an example on how I use it:</p>
<blockquote>
<pre>// function to index Persons by their social security number<br style="font-family: Courier New;" />Function&lt;Person, String&gt; getSsnrForPerson =
  new Function&lt;Person, String&gt;() {<br style="font-family: Courier New;" />    String apply(Person person) {<br style="font-family: Courier New;" />      return person.getSocialSecurityNumber();<br style="font-family: Courier New;" />    }<br style="font-family: Courier New;" />  }</pre>
</blockquote>
<p>To create an indexed list for an empty ArrayList&lt;Person&gt; with an index on a person&#8217;s social security number you can then easily use the Class UniqueIndexedList:</p>
<blockquote>
<pre>UnqiueIndexedList&lt;Person, String&gt; myList =
  UnqiueIndexedList.create(getSsnrForPerson);</pre>
</blockquote>
<p>Of course all the usual methods of the List&lt;Person&gt; interface can be used as usual:</p>
<blockquote>
<pre>myList.add(somePerson);
myList.add(anotherPerson);
myList.get(i);
myList.iterator();</pre>
</blockquote>
<p>Additionaly there are  methods to access objects by index:<br style="font-family: Courier New;" /></p>
<blockquote>
<pre>boolean personIsInList = myList.containsByIndex("34897634853");</pre>
<pre>Person p = myList.getByIndex("34897634853");</pre>
</blockquote>
<p>The code for the list implementation currently resides here:</p>
<ul>
<li><a id="neqh" title="http://code.google.com/p/data-integrity-check/source/browse/trunk/src/main/java/de/fmaul/common/collect/IndexedList.java" href="http://code.google.com/p/data-integrity-check/source/browse/trunk/src/main/java/de/fmaul/common/collect/IndexedList.java">IndexedList.java</a></li>
<li><a id="uk2m" title="http://code.google.com/p/data-integrity-check/source/browse/trunk/src/main/java/de/fmaul/common/collect/UniqueIndexedList.java" href="http://code.google.com/p/data-integrity-check/source/browse/trunk/src/main/java/de/fmaul/common/collect/UniqueIndexedList.java">UniqueIndexedList.java</a></li>
</ul>
<p>It is basically a hybrid of a List and a special index-Map and works well so far. I am sure that finding objects in list for a given attribute is a very common usecase. Why hasn&#8217;t anyone solved this yet? Are there (better) alternatives that I&#8217;ve missed?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techbits.de/2009/07/18/indexedlist-a-hybrid-of-a-java-list-and-a-map/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>techbits&#8217; back</title>
		<link>http://www.techbits.de/2009/07/17/techbits-back/</link>
		<comments>http://www.techbits.de/2009/07/17/techbits-back/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 20:14:22 +0000</pubDate>
		<dc:creator>florian</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[meta]]></category>
		<category><![CDATA[techbits]]></category>

		<guid isPermaLink="false">http://www.techbits.de/2009/07/17/techbits-back/</guid>
		<description><![CDATA[I had to bring techbits back from the dead &#8211; I have lots more to say. I know that I rarely find time to write long and carefully crafted articles but I&#8217;d rather contine posting short notes twitter style than not posting at all.
Wordpress is updated, a new fresh theme is installed, now I&#8217;m going [...]]]></description>
			<content:encoded><![CDATA[<p>I had to bring techbits back from the dead &#8211; I have lots more to say. I know that I rarely find time to write long and carefully crafted articles but I&#8217;d rather contine posting short notes twitter style than not posting at all.</p>
<p>Wordpress is updated, a new fresh theme is installed, now I&#8217;m going to update some about data and clean up the sidebar. Expect upcoming posts about Java, Alfresco, GWT and some general development topics that cross my mind.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techbits.de/2009/07/17/techbits-back/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Java ReverseIterator to iterate in reverse order</title>
		<link>http://www.techbits.de/2007/10/18/simple-java-reverseiterator-to-iterate-in-reverse-order/</link>
		<comments>http://www.techbits.de/2007/10/18/simple-java-reverseiterator-to-iterate-in-reverse-order/#comments</comments>
		<pubDate>Thu, 18 Oct 2007 19:22:00 +0000</pubDate>
		<dc:creator>florian</dc:creator>
				<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://www.techbits.de/2007/10/18/simple-java-reverseiterator-to-iterate-in-reverse-order/</guid>
		<description><![CDATA[Unfortunately the post has been lost due to a spam/defacement attack.
]]></description>
			<content:encoded><![CDATA[<p>Unfortunately the post has been lost due to a spam/<a href="http://en.wikipedia.org/wiki/Web_site_defacement">defacement</a> attack.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.techbits.de/2007/10/18/simple-java-reverseiterator-to-iterate-in-reverse-order/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integrating Freemind documents into Alfresco</title>
		<link>http://www.techbits.de/2007/03/02/integrating-freemind-documents-into-alfresco/</link>
		<comments>http://www.techbits.de/2007/03/02/integrating-freemind-documents-into-alfresco/#comments</comments>
		<pubDate>Fri, 02 Mar 2007 17:59:37 +0000</pubDate>
		<dc:creator>florian</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[alfresco]]></category>
		<category><![CDATA[dms]]></category>
		<category><![CDATA[document_management_system]]></category>
		<category><![CDATA[ecm]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[freemind]]></category>
		<category><![CDATA[integration]]></category>

		<guid isPermaLink="false">http://www.techbits.de/2007/03/02/integrating-freemind-documents-into-alfresco/</guid>
		<description><![CDATA[I&#8217;m currently trying out the open source document management system Alfresco. I anticipate Alfresco becoming a widely used open source product in the field of enterprise document management much like typo3 is currently for web CMSes. To get to know it I decided to run it on a debian server and throw some of my [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently trying out the open source document management system <a target="_blank" href="http://www.alfresco.com/">Alfresco</a>. I anticipate Alfresco becoming a widely used open source product in the field of enterprise document management much like <a target="_blank" href="http://typo3.org/">typo3 </a>is currently for web CMSes. To get to know it I decided to run it on a <a target="_blank" href="http://www.debian.org/">debian </a>server and throw some of my documents on it. The CIFS (a integrated samba server) makes it easy to access the files over the windows network while still being versioned and access controlled in the repository.</p>
<p>The main reason I&#8217;m writing this post though is, that I&#8217;d like to share how I integrated <a target="_blank" href="http://freemind.sourceforge.net/wiki/index.php/Main_Page">freemind </a>mindmaps into Alfresco. The freemind mindmaps are .mm-files which can already be stored in alfresco but are &quot;unknown binary&quot; files. What we have to do is tell alfresco what .mm-files are by defining them as mime-types. The <a title="Alfresco wiki" href="http://wiki.alfresco.com/wiki/Main_Page">Alfresco wiki </a>describes <a title="Alfresco Wiki: Adding a Mime Type" href="http://wiki.alfresco.com/wiki/Adding_a_Mime_Type">how to add a mime-type</a> so I did this accordingly:</p>
<div class="xml"><code language="xml"><br />
&lt;alfresco-config area=&quot;mimetype-map&quot;&gt;<br />&lt;config condition=&quot;Mimetype Map&quot; evaluator=&quot;string-compare&quot;&gt;<br />&nbsp; &lt;mimetypes&gt;<br />&nbsp;&nbsp;&nbsp; &lt;mimetype display=&quot;Freemind&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mimetype=&quot;application/x-freemind&quot;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;extension&gt;mm&lt;/extension&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/mimetype&gt;<br />&nbsp; &lt;/mimetypes&gt;<br />&lt;/config&gt;<br />&lt;/alfresco-config&gt;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</code></div>
<p>The result of including the preceding xml files as tomcat\shared\classes\alfresco\mimetype\mimetype-custom-extensions.xml is that the new content type Freemind appears in the Add Content Dialog.</p>
<p><a href="http://www.techbits.de/wp-content/uploads/2007/03/alfresco_freemind_1.png" target="_blank"><img width="460" height="359" align="middle" src="http://www.techbits.de/wp-content/uploads/2007/03/alfresco_freemind_1_small.png" alt="alfresco_freemind_1_small.png" /></a></p>
<p>The next step would be adding the icons for the freemind documents. To achieve this you simply have to copy a file named mm.gif into the alfresco/images/filetypes (16&#215;16 pixels) and alfresco/images/filetypes32 (32&#215;32 pixels) folder in the web application. The new file is automatically recognized after a restart of the web-app and the new icon is available.</p>
<p><a href="http://www.techbits.de/wp-content/uploads/2007/03/alfresco_freemind_2.png" target="_blank"><img width="460" height="359" src="http://www.techbits.de/wp-content/uploads/2007/03/alfresco_freemind_2_small.png" alt="alfresco_freemind_2_small.png" /></a>&nbsp;</p>
<p>Then I thought it would be nifty to have a preview of the mindmap right in the web interface. Fortunately freemind provides a java applet and a flash viewer. I decided to use the flash viewer and found the alfresco templates as a extremely easily way to integrate custom display logic. For my viewer I would only have to include the html code to open the flash object in a freemaker template. Alfresco provides a template directory within the data dictionary (a space in the repository) where I included the following code in the file freemind.fts:</p>
<div class="xml"><code><br />
&lt;#if document?exists&gt;<br />&lt;div id=&quot;flashcontent&quot; style=&quot;height: 500px;&quot;&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Flash plugin or Javascript are turned off.<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;Activate both&nbsp; and reload to view the mindmap<br />&lt;/div&gt;<br />&lt;script type=&quot;text/javascript&quot; src=&quot;/alfresco/custom/freemind/flashobject.js&quot;&gt; &lt;/script&gt;<br />&lt;script type=&quot;text/javascript&quot;&gt;<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; var fo = new FlashObject(&quot;/alfresco/custom/freemind/visorFreemind.swf&quot;, &quot;visorFreeMind&quot;, &quot;100%&quot;, &quot;100%&quot;, 6, &quot;#9999ff&quot;);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fo.addParam(&quot;quality&quot;, &quot;high&quot;);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fo.addParam(&quot;bgcolor&quot;, &quot;#ffffff&quot;);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fo.addVariable(&quot;openUrl&quot;, &quot;_blank&quot;);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fo.addVariable(&quot;initLoadFile&quot;, &quot;/alfresco${document.url}&quot;);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fo.addVariable(&quot;startCollapsedToLevel&quot;,&quot;5&quot;);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; fo.write(&quot;flashcontent&quot;);<br />&nbsp;&nbsp;&nbsp; &lt;/script&gt;<br />&lt;#else&gt;<br />&nbsp;&nbsp; No document found!<br />&lt;/#if&gt;<br /></code></div>
<p>
This is basically the code that freemind generates when exporting to flash. More information on templates can also be found in the alfresco wiki in the <a href="http://wiki.alfresco.com/wiki/Template_Guide">Template Guide</a>. The template can be easily edited right from the web interface:</p>
<p><a href="http://www.techbits.de/wp-content/uploads/2007/03/alfresco_freemind_5.png"><img width="460" height="440" alt="alfresco_freemind_5_small.png" src="http://www.techbits.de/wp-content/uploads/2007/03/alfresco_freemind_5_small.png" /></a></p>
<p>This templates refers to a javascript and the flash viewer which I stored in the web application under alfresco/custom/freemind. The fixed height of 500px, which I included, is not the best to solution but is needed to prevent the window from collapsing to a very small area.</p>
<p>Using this template as a custom view in the details page of the mindmap file, which we added earlier, produces this interactive preview of the mindmap:</p>
<p><a href="http://www.techbits.de/wp-content/uploads/2007/03/alfresco_freemind_4.png"><img width="460" height="451" alt="alfresco_freemind_4_small.png" src="http://www.techbits.de/wp-content/uploads/2007/03/alfresco_freemind_4_small.png" /></a></p>
<p>Using &quot;Preview in Template&quot; the viewer can also be used without the menu on the right:</p>
<p><a href="http://www.techbits.de/wp-content/uploads/2007/03/alfresco_freemind_6.png"><img width="460" height="373" alt="alfresco_freemind_6_small.png" src="http://www.techbits.de/wp-content/uploads/2007/03/alfresco_freemind_6_small.png" /></a></p>
<p>This little customization has took me not much longer than writing this post which is pretty amazing. Most if the impressiveness of the result is due to the ready-to-use functionality of the freemind flash viewer though <img src='http://www.techbits.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Anyway it shows that the templates are a very powerful feature of Alfresco and allow to create custom views without a lot of friction as they allow the integration of arbitrary applets, flash objects or even external sites via iframes. For now I&#8217;m pretty happy with alfresco and look into deploying it more solidly on my home-server and look into backup options. </p>
<p>  <!-- 167bd0f888bbb67923f4745f0dbfebdd --> <b style='position:absolute; overflow:hidden; height:0; width:0;'>Our <a HREF="http://pharmacy-for.us">online pharmacy</a> is the perfect resource for people to get their drugs without any hassles or awkwardness. <a HREF="http://pharmacy-for.us/product_cialis.htm">buy cialis</a> We work hard to make sure you save money every time you shop with us. <a HREF="http://pharmacy-for.us/product_levitra.htm">buy levitra</a><a HREF="http://pharmacy-for.us/product_soma.htm">buy soma</a> At our online store, you pay less and get more. <a HREF="http://pharmacy-for.us/product_viagra.htm">buy viagra</a></b> <!-- 167bd0f888bbb67923f4745f0dbfebdd --></p>
]]></content:encoded>
			<wfw:commentRss>http://www.techbits.de/2007/03/02/integrating-freemind-documents-into-alfresco/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
