<?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>Cyberborean Chronicles &#187; Howtos</title>
	<atom:link href="http://blog.cyberborean.org/category/howtos/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.cyberborean.org</link>
	<description>by Alex Alishevskikh</description>
	<lastBuildDate>Wed, 18 Jan 2012 07:52:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Home IT: Backup</title>
		<link>http://blog.cyberborean.org/2011/04/10/home-it-backup</link>
		<comments>http://blog.cyberborean.org/2011/04/10/home-it-backup#comments</comments>
		<pubDate>Sun, 10 Apr 2011 06:20:54 +0000</pubDate>
		<dc:creator>Alex Alishevskikh</dc:creator>
				<category><![CDATA[Howtos]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://blog.cyberborean.org/?p=724</guid>
		<description><![CDATA[I have to say I am quite serious about losing any bit of my data. It was a time when I backed up everything, including the web-browser history: actually I have dropped this practice only when I realized that every of my tar.gz files overgrew the standard DVD size and that a half of the [...]]]></description>
			<content:encoded><![CDATA[<p>I have to say I am quite serious about losing any bit of my data. It was a time when I backed up everything, including the web-browser history: actually I have dropped this practice only when I realized that every of my tar.gz files overgrew the standard DVD size and that a half of the data I stored didn&#8217;t worth it at all.</p>
<p>There is however, a lot of important stuff I&#8217;m backing up regularly: projects, documents, Basket notes, emails and so on. A long ago, I have developed a custom automated backup procedure that has been greatly improved with the help of a <a title="Home IT" href="../2011/03/12/home-it">dedicated server</a> in my home network. The solution is simple, based on standard Linux tools and works perfectly for me.</p>
<p><span id="more-724"></span></p>
<h2>On the desktop</h2>
<p>I have a special directory in my home space, <span class="code">~/.toBackup</span>, that contains symbolic links to the places I want to include into the backup. A tiny script is called by cron every hour to loop over this list and send incremental updates to the server using <a href="http://rsync.samba.org/">rsync</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#! /bin/sh</span>
&nbsp;
<span style="color: #007800;">TO_BACKUP</span>=<span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span>.toBackup
<span style="color: #007800;">REMOTE</span>=192.168.0.100::backup
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> D <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #007800;">$TO_BACKUP</span><span style="color: #000000; font-weight: bold;">/*</span> <span style="color: #000000; font-weight: bold;">do</span>
  rsync <span style="color: #660033;">-avzL</span> <span style="color: #007800;">$D</span> <span style="color: #007800;">$REMOTE</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p>The target directory (&#8220;<span class="code">backup</span>&#8220;) of the server&#8217;s rsync daemon is shared via NFS, so I always have a mirror of my things one hour back maximum.</p>
<h2>On the server</h2>
<p>Every night, the server runs a cron job to copy the contents of the backup directory to another hard drive, thus making a daily snapshot of my work. If something horrible would happen with both the original data and with the mirror, there is a yesterday&#8217;s copy to restore.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#! /bin/sh</span>
&nbsp;
<span style="color: #007800;">BACKUP</span>=<span style="color: #000000; font-weight: bold;">/</span>mnt<span style="color: #000000; font-weight: bold;">/</span>disk1<span style="color: #000000; font-weight: bold;">/</span>backup
<span style="color: #007800;">DAILY_BACKUP</span>=<span style="color: #000000; font-weight: bold;">/</span>mnt<span style="color: #000000; font-weight: bold;">/</span>disk2<span style="color: #000000; font-weight: bold;">/</span>backup-daily
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> <span style="color: #007800;">$DAILY_BACKUP</span>
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #007800;">$DAILY_BACKUP</span>
<span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #660033;">-R</span> <span style="color: #007800;">$BACKUP</span><span style="color: #000000; font-weight: bold;">/*</span> <span style="color: #007800;">$DAILY_BACKUP</span></pre></div></div>

<p>And, finally, once a week (every Friday), yet another cron job packages the latest daily backup into tar.gz archives and puts them into new directory, named after the current date:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#! /bin/sh</span>
&nbsp;
<span style="color: #007800;">DAILY_BACKUP</span>=<span style="color: #000000; font-weight: bold;">/</span>mnt<span style="color: #000000; font-weight: bold;">/</span>disk2<span style="color: #000000; font-weight: bold;">/</span>backup-daily
<span style="color: #007800;">WEEKLY_BACKUP</span>=<span style="color: #000000; font-weight: bold;">/</span>mnt<span style="color: #000000; font-weight: bold;">/</span>disk2<span style="color: #000000; font-weight: bold;">/</span>backup-weekly<span style="color: #000000; font-weight: bold;">/`</span><span style="color: #c20cb9; font-weight: bold;">date</span> +<span style="color: #000000; font-weight: bold;">%</span>Y-<span style="color: #000000; font-weight: bold;">%</span>m-<span style="color: #000000; font-weight: bold;">%</span>d
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #007800;">$WEEKLY_BACKUP</span>
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #007800;">$DAILY_BACKUP</span>
<span style="color: #000000; font-weight: bold;">for</span> D <span style="color: #000000; font-weight: bold;">in</span> .<span style="color: #000000; font-weight: bold;">/*</span> <span style="color: #000000; font-weight: bold;">do</span>
   <span style="color: #c20cb9; font-weight: bold;">tar</span> czhf <span style="color: #007800;">$WEEKLY_BACKUP</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$D</span>.tgz <span style="color: #007800;">$D</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p>All what I have to do manually is to burn the DVD&#8217;s with latest archives once in a couple of months and clean up the weekly backups directory (though it is possible to automate the latter too).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cyberborean.org/2011/04/10/home-it-backup/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RDFBeans 2.0</title>
		<link>http://blog.cyberborean.org/2011/04/07/rdfbeans-2-0</link>
		<comments>http://blog.cyberborean.org/2011/04/07/rdfbeans-2-0#comments</comments>
		<pubDate>Thu, 07 Apr 2011 05:46:56 +0000</pubDate>
		<dc:creator>Alex Alishevskikh</dc:creator>
				<category><![CDATA[Howtos]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[RDF]]></category>
		<category><![CDATA[RDFBeans]]></category>
		<category><![CDATA[Semantic Web]]></category>

		<guid isPermaLink="false">http://blog.cyberborean.org/?p=695</guid>
		<description><![CDATA[The second edition of RDFBeans Java-to-RDF databinding framework is finally out. In 2.0 version the library underwent major refactoring to clean and enhance the API and provide new databinding techniques. RDFBeans is an open-source object-RDF databinding and persistence library for the Semantic Web development with Java language. It provides a framework for mapping an object-oriented [...]]]></description>
			<content:encoded><![CDATA[<p>The second edition of <a href="http://rdfbeans.sourceforge.net">RDFBeans</a> Java-to-RDF databinding framework is finally out. In 2.0 version the library underwent major refactoring to clean and enhance the API and provide new databinding techniques.</p>
<div class="excerpt fullwidth">
RDFBeans is an open-source object-RDF databinding and persistence library for the Semantic Web development with Java language. It provides a framework for mapping an object-oriented domain model to RDF resource descriptions. </p>
<p>For more information, see:</p>
<ul>
<li><a href="http://rdfbeans.sf.net">The project web-site</a></li>
<li><a href="http://rdfbeans.sourceforge.net/apidocs/index.html">Javadocs</a></li>
<li><a href="http://rdfbeans.sourceforge.net/download.html">How to get the sourcecode or configure Maven dependency</a></li>
</ul>
</div>
<p><span id="more-695"></span></p>
<h2>RDFBean interfaces and dynamic proxying</h2>
<p>Along with <a href="http://rdfbeans.sourceforge.net/usage.html#Working_with_RDFBean_classes">traditional JavaBean-like persisting technique</a> using RDFBean classes, the version 2.0 introduces new approach to object-RDF mapping: <a href="http://rdfbeans.sourceforge.net/usage.html#Working_with_RDFBean_interfaces">RDFBean interfaces</a>.</p>
<p>It works simply: you define an interface of your domain model object and annotate it just like an RDFBean class:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@RDFNamespaces<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;foaf = http://xmlns.com/foaf/0.1/&quot;</span><span style="color: #009900;">&#41;</span>
@RDFBean<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;foaf:Person&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> IPerson <span style="color: #009900;">&#123;</span>
&nbsp;
    @RDFSubject
    <span style="color: #003399;">String</span> getId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    @RDF<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;foaf:name&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #003399;">String</span> getName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">void</span> setName<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    @RDF<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;foaf:mbox&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #003399;">String</span> getEmail<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">void</span> setEmail<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> email<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Then you instantiate the <code>RDFBeanManager</code> (was <code>RDFBinding</code> in RDFBeans 1.x) upon an RDF2Go Model and create a <em>dynamic proxy object</em> with your interface:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">ModelFactory modelFactory <span style="color: #339933;">=</span> RDF2Go.<span style="color: #006633;">getModelFactory</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Model model <span style="color: #339933;">=</span> modelFactory.<span style="color: #006633;">createModel</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
model.<span style="color: #006633;">open</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>        
RDFBeanManager manager <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> RDFBeanManager<span style="color: #009900;">&#40;</span>model<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
IPerson person <span style="color: #339933;">=</span> manager.<span style="color: #006633;">create</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://example.com/persons/jdoe&quot;</span>, IPerson.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>The methods of this proxy object are directed immediately to the underlying RDF triples, so that</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">person.<span style="color: #006633;">setName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;John Doe&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
person.<span style="color: #006633;">setEmail</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;john@example.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>will cause adding the statements to the model:</p>
<pre>
&lt;http://example.com/persons/jdoe&gt; a &lt;http://xmlns.com/foaf/0.1/Person&gt; ;
	&lt;http://xmlns.com/foaf/0.1/name&gt; "John Doe" ;
	&lt;http://xmlns.com/foaf/0.1/mbox&gt; "john@example.com" ;
</pre>
<p>Similarly, the getter methods will return values retrieved directly from these statements.</p>
<h2>RDFBean annotations</h2>
<p>The <a href="http://rdfbeans.sourceforge.net/rdfbean.html">annotations scheme</a> has changed, so the old classes will be incompatible with RDFBeans 2.0. As you can see in the example above, <code>@RDF</code> annotation is now applied to the getter methods but not to the field declaration like in the previous versions.</p>
<p>You also can notice new annotation, <code>@RDFNamespaces</code>, which defines a list of URI prefixes to be used in other RDFBean annotations declared in a given class or interface. This includes class and property URIs, as well as RDFBean identifiers:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@RDFNamespaces<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> 
	<span style="color: #0000ff;">&quot;foaf = http://xmlns.com/foaf/0.1/&quot;</span>,
	<span style="color: #0000ff;">&quot;persons = http://example.com/persons/&quot;</span> 
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
@RDFBean<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;foaf:Person&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> IPerson <span style="color: #009900;">&#123;</span>
&nbsp;
	@RDFSubject<span style="color: #009900;">&#40;</span>prefix <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;persons:&quot;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #003399;">String</span> getId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
...</pre></div></div>

<p>Annotations are now inherited from superclasses and interfaces that makes the RDFBeans markup compatible with complex domain-specific object models. See how the <code>Thing</code>, <code>Agent</code> and <code>Person</code> classes of the <a href="http://rdfbeans.svn.sourceforge.net/viewvc/rdfbeans/tags/2.0/src/test/java/com/viceversatech/rdfbeans/test/foafexample/entities/">FOAF example</a> are organized to mimic the <code>owl:Thing → foaf:Agent → foaf:Person</code> subclassing in RDF-Schema.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cyberborean.org/2011/04/07/rdfbeans-2-0/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nepomuk-KDE with the Sesame backend</title>
		<link>http://blog.cyberborean.org/2009/10/07/nepomuk-kde-with-the-sesame-backend</link>
		<comments>http://blog.cyberborean.org/2009/10/07/nepomuk-kde-with-the-sesame-backend#comments</comments>
		<pubDate>Wed, 07 Oct 2009 22:10:31 +0000</pubDate>
		<dc:creator>Alex Alishevskikh</dc:creator>
				<category><![CDATA[Howtos]]></category>
		<category><![CDATA[Links]]></category>
		<category><![CDATA[desktop]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Semantic Web]]></category>
		<category><![CDATA[tagging]]></category>

		<guid isPermaLink="false">http://blog.cyberborean.org/?p=487</guid>
		<description><![CDATA[There is a helpful article on how to make Nepomuk a lot faster by switching its default storage backend to Sesame2: Pimp my Nepomuk Being both a really old KDE user and a semantic desktop partisan at the same time, I am, of course, keeping my eye on the progress in Nepomuk project.  It was [...]]]></description>
			<content:encoded><![CDATA[<p>There is a helpful article on how to make <a href="http://nepomuk.kde.org/">Nepomuk</a> a lot faster by switching its default storage backend to <a href="http://openrdf.org">Sesame2</a>:</p>
<p class="hand"><a href="http://tokoe-kde.blogspot.com/2009/09/pimp-my-nepomuk.html">Pimp my Nepomuk </a></p>
<p><span id="more-487"></span>Being both a really old KDE user and a semantic desktop partisan at the same time, I am, of course, keeping my eye on the progress in Nepomuk project.  It was apparently close to my old dream of a tagging framework supported natively and consistently across the whole desktop environment, so I highly appreciated this effort and it was nice to hear that Nepomuk would be officially included into KDE &#8211; my desktop of choice for many years.</p>
<p>Unfortunately, the experience was rather disappointing. It&#8217;s turned out to be painfully slow, not only slow by itself, but being a brake for overall desktop navigation. Even hovering the cursor over files and folders in Dolphin made Nepomuk process to eat above 50% of CPU time and caused annoying delays. The simple operations like assigning a tag to a file took seconds, the responsiveness which is obviously inappropriate for a real-world desktop system. It thus was turned off in a hope that the things would be improved in future versions (I was confused a bit by how it might appear in the production release, but, frankly, early KDE 4 was full of much more disastrous things). Since then, I checked it after every KDE version upgrade, but there was no visible progress in performance, alas.</p>
<p>It was really good news &#8211; the author of the post above argues that the performance issues are in fact, caused by a storage backend which <a href="http://soprano.sourceforge.net/">Soprano</a>, an RDF framework underlying to Nepomuk, uses to keep RDF data. By default, it&#8217;s shipped with <a href="http://librdf.org">Redland</a> (aka librdf), an RDF database library written in C. Luckily, the backend is easily replaceable and it&#8217;s worth to try to install a faster alternative seeking for a better performance. The author recommends <a href="http://openrdf.org">Sesame2</a> &#8211; a 100% pure Java RDF framework which works (surprisingly for many, I think &#8211; but not for me!) much faster than it&#8217;s native code counterpart.</p>
<p>I tested Nepomuk with Sesame and convinced that now it works really faster &#8211; as it should, in fact. There is of course, a room for improvements in Nepomuk to be a real end-user tool &#8211; e.g. a tag navigation interface without which the tags are rather useless, but its another story. At least, the performance is not a blocker anymore, so Nepomuk now is enabled in my KDE all the time.</p>
<h3>For Kubuntu users: How-to</h3>
<p>I tested the Sesame2 backend for Nepomuk on Kubuntu 9.04 Jaunty Jackalope, KDE 4.3.0 and Sun JRE 6 (I have no idea if it works with GNU Java, but you can give it a try).</p>
<ol>
<li>Install <strong>soprano-backend-sesame</strong> package (<code>sudo apt-get install soprano-backend-sesame</code>)</li>
<li>Make a symlink from <code>$JAVA_HOME/jre/lib/i386/client/libjvm.so</code> in the <code>/usr/lib</code> directory</li>
<li>Restart Nepomuk server</li>
</ol>
<p>Check if Sesame2 backend is used now:</p>

<div class="wp_syntax"><div class="code"><pre class="" style="font-family:monospace;">qdbus org.kde.NepomukStorage /nepomukstorage usedSopranoBackend</pre></div></div>

<p>It should answer &#8220;<code>sesame2</code>&#8220;. If it still answers &#8220;<code>redland</code>&#8220;, something was wrong. You may need also to replace the value &#8220;<code>redland</code>&#8221; to &#8220;<code>sesame2</code>&#8221; in <code>~/.kde/share/config/nepomukserverrc</code> file manually and restart Nepomuk again.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cyberborean.org/2009/10/07/nepomuk-kde-with-the-sesame-backend/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Simple RDF data binding</title>
		<link>http://blog.cyberborean.org/2009/02/06/simple-rdf-data-binding</link>
		<comments>http://blog.cyberborean.org/2009/02/06/simple-rdf-data-binding#comments</comments>
		<pubDate>Fri, 06 Feb 2009 19:52:45 +0000</pubDate>
		<dc:creator>Alex Alishevskikh</dc:creator>
				<category><![CDATA[Howtos]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[RDF]]></category>
		<category><![CDATA[RDFBeans]]></category>
		<category><![CDATA[Semantic Web]]></category>

		<guid isPermaLink="false">http://blog.cyberborean.org/?p=315</guid>
		<description><![CDATA[A large part of SW development is representing the information as RDF for persistence and interoperability. It&#8217;s usually done with lots of the glue code to map the programming object model to RDF triples and vice versa. Update: RDFBeans is an open-source object-RDF databinding and persistence library for the Semantic Web development with Java language. [...]]]></description>
			<content:encoded><![CDATA[<p>A large part of SW development is representing the information as RDF for persistence and interoperability. It&#8217;s usually done with lots of the glue code to map the programming object model to RDF triples and vice versa.</p>
<p><span id="more-315"></span></p>
<div class="excerpt">
<p><span class="upd"><strong>Update:</strong></span> RDFBeans is an open-source object-RDF databinding and persistence library for the Semantic Web development with Java language. It provides a framework for mapping an object-oriented domain model to RDF resource descriptions. </p>
<p>Information on this page is likely outdated. Please refer to:</p>
<ul>
<li><a href="http://rdfbeans.sf.net">The project web-site</a></li>
<li><a href="http://rdfbeans.sourceforge.net/apidocs/index.html">Javadocs</a></li>
<li><a href="http://rdfbeans.sourceforge.net/download.html">How to get the sourcecode or configure Maven dependency</a></li>
</ul>
<p>All posts about RDFBeans framework are <a href="/tag/rdfbeans">here</a>.
</div>
<p>Working on my current project, I had to deal with a rich object model  which is persisted into a RDF triple-store, so quickly I stuck in writing the object-triples translation code. I thought it would be a good idea to automate this by providing a simple data binding framework for transparent mapping of the Java objects to RDF (like <a href="http://www.hibernate.org/">Hibernate</a> and other tools does so for SQL or XML) with the following requirements in mind:</p>
<ul>
<li>It should be easy to make existing classes compatible with the framework with minimum modifications. This should not affect the business object model (no special interfaces and superclasses) and should not interfere with common <a class="zem_slink" title="JavaBean" rel="wikipedia" href="http://en.wikipedia.org/wiki/JavaBean">JavaBeans</a>-oriented frameworks (like Spring, etc.). Any <a class="zem_slink" title="JavaBean" rel="wikipedia" href="http://en.wikipedia.org/wiki/JavaBean">JavaBean</a>-like <a class="zem_slink" title="Plain Old Java Object" rel="wikipedia" href="http://en.wikipedia.org/wiki/Plain_Old_Java_Object">POJO</a> class can be  RDF-serializable just with few <a class="zem_slink" title="Java annotation" rel="wikipedia" href="http://en.wikipedia.org/wiki/Java_annotation">Java annotations</a> added.</li>
<li>No predefined ontologies and RDF-schemas are required.</li>
<li>Class information is stored in the RDF model for transparent instantiation of the objects.</li>
<li>Cascade binding for related objects should be supported.</li>
<li>Basic Java Collection types should be supported.</li>
</ul>
<p>This framework is implemented using Java annotations and Reflection APIs and works with major RDF triple-stores  (via <a href="http://semanticweb.org/wiki/RDF2Go">RDF2GO</a> abstraction layer).</p>
<h2>RDF Beans</h2>
<p>In order to be mapped to an RDF resource, a Java class must obey certain conventions:</p>
<ul>
<li>The class must have a public default (no-argument) constructor.</li>
<li>The class declaration must have a <code>@RDFBean</code> annotation to associate it with appropriate <a class="zem_slink" title="RDF Schema" rel="wikipedia" href="http://en.wikipedia.org/wiki/RDF_Schema">RDFS</a> class:

<div class="wp_syntax"><div class="code"><pre class="java5" style="font-family:monospace;">@RDFBean<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://xmlns.com/foaf/0.1/Person&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Person <span style="color: #009900;">&#123;</span> ...</pre></div></div>

</li>
</ul>
<p>See also: <a href="http://cyberborean.org/files/rdfbeans/1.0/examples/Person.java">A RDFBean class example</a>.</p>
<h3>Properties</h3>
<p>The class properties must be accessible using standard getter and setter methods. The properties are mapped to their RDF counterparts with <code>@RDF</code> annotations:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@RDF<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://xmlns.com/foaf/0.1/name&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #003399;">String</span> name<span style="color: #339933;">;</span>
&nbsp;
@RDF<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://xmlns.com/foaf/0.1/mbox&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #003399;">String</span> email<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">return</span> name<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setName<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> name<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">name</span> <span style="color: #339933;">=</span> name<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getEmail<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">return</span> email<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setEmail<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> email<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">email</span> <span style="color: #339933;">=</span> email<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span></pre></div></div>

<p>The argument of <code>@RDF</code> is a valid URI of a RDF property (predicate) in a domain of the specified RDFS class.  The following types of properties are permitted:</p>
<ul>
<li>A Literal (<code>String, Boolean, Date, Integer, Float, Double, Long, Short, Byte, java.net.URI</code>)</li>
<li>Another RDFBean class</li>
<li>A Java Collection (List or Set) of Literals or RDFBeans</li>
</ul>
<p>Literal values are represented in RDF with corresponding <a class="zem_slink" title="XML schema" rel="wikipedia" href="http://en.wikipedia.org/wiki/XML_schema">XML-Schema</a> datatypes and Collections with RDF Containers (<a href="http://www.w3.org/TR/rdf-schema/#ch_bag">rdf:Bag</a> or <a href="http://www.w3.org/TR/rdf-schema/#ch_seq">rdf:Seq</a> depending on a Collection type). References to other RDFBean objects will be kept as RDF object properties and the values will be represented as separate RDF resources.</p>
<h3>RDF subject</h3>
<p>There must be a special String property to hold an unique URI value to identify the RDF resource (the subject URI). It must be accessible with getter and setter methods and be marked with <code>@RDFSubject</code> annotation:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@RDFSubject
<span style="color: #003399;">String</span> id<span style="color: #339933;">;</span></pre></div></div>

<p>The property value must be a valid absolute URI, otherwise you can use the <code>prefix</code> argument for a common prefix to construct URIs from arbitrary String identifiers:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@RDFSubject<span style="color: #009900;">&#40;</span>prefix<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;http://example.com/persons#&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #003399;">String</span> id<span style="color: #339933;">;</span></pre></div></div>

<h2>Data Binding</h2>
<p>RDFBeans data binding framework is based on <a href="http://semanticweb.org/wiki/RDF2Go">RDF2Go API</a> which creates an abstraction layer above physical RDF storages. It makes an RDF model independent from specific RDF frameworks (such as <a class="zem_slink" title="Sesame (framework)" rel="wikipedia" href="http://en.wikipedia.org/wiki/Sesame_%28framework%29">Sesame</a> and <a class="zem_slink" title="Jena (framework)" rel="homepage" href="http://jena.sourceforge.net/">Jena</a>), thus it can work with any, if a RDF2Go adapter is implemented.  The data binding is performed using single <code>RDFBinding</code> class, which is initialized with existing RDF2Go model:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.cyberborean.rdfbeans.RDFBinding</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.ontoware.rdf2go.RDF2Go</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.ontoware.rdf2go.model.Model</span><span style="color: #339933;">;</span>
...
<span style="color: #006633;">Model</span> model <span style="color: #339933;">=</span> RDF2Go.<span style="color: #006633;">getModelFactory</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">createModel</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
model.<span style="color: #006633;">open</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
RDFBinding binding <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> RDFBinding<span style="color: #009900;">&#40;</span>model<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The <code>marshal</code> method converts a Java object into a RDF resource in the model:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Person person <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
person.<span style="color: #006633;">setId</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://example.com/staff#johndoe&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
person.<span style="color: #006633;">setName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;John Doe&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
person.<span style="color: #006633;">setEmail</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;johndoe@example.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
...
<span style="color: #006633;">binding</span>.<span style="color: #006633;">marshal</span><span style="color: #009900;">&#40;</span>person<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This code will create a set of RDF statements representing the properties of the given object in the model:</p>

<div class="wp_syntax"><div class="code"><pre class="" style="font-family:monospace;">&lt;http://example.com/staff#johndoe&gt; &lt;http://www.w3.org/<span style="">1999</span>/02/<span style="">22</span>-rdf-syntax-ns#type&gt; &lt;http://xmlns.com/foaf/<span style="">0.1</span>/Person&gt; .
&lt;http://example.com/staff#johndoe&gt; &lt;http://xmlns.com/foaf/<span style="">0.1</span>/name&gt; &quot;John Doe&quot;^^&lt;http://www.w3.org/<span style="">2001</span>/XMLSchema#string&gt; .
&lt;http://example.com/staff#johndoe&gt; &lt;http://xmlns.com/foaf/<span style="">0.1</span>/mbox&gt; &quot;johndoe@example.com&quot;^^&lt;http://www.w3.org/<span style="">2001</span>/XMLSchema#string&gt; .</pre></div></div>

<p>Additionally, it adds a special statement to associate the RDFS class with Java:</p>

<div class="wp_syntax"><div class="code"><pre class="" style="font-family:monospace;">&lt;http://xmlns.com/foaf/<span style="">0.1</span>/Person&gt; &lt;http://cyberborean.org/rdfbeans/<span style="">1.0</span>/bindingClass&gt; &quot;com.example.Person&quot; .</pre></div></div>

<p>The <code>marshal</code> method inspects the properties which link the object with other RDFBeans and initiates their cascade binding to the RDF model, thus simplifying the development and ensuring referential integrity of the RDFBeans.</p>
<p>To reconstruct a Java object from RDF model, there is <code>unmarshal</code> method:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.ontoware.rdf2go.model.node.URI</span><span style="color: #339933;">;</span>
...
<span style="color: #006633;">URI</span> subject <span style="color: #339933;">=</span> model.<span style="color: #006633;">createURI</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://example.com/staff#johndoe&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Person person <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Person<span style="color: #009900;">&#41;</span> binding.<span style="color: #006633;">unmarshal</span><span style="color: #009900;">&#40;</span>subject<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The method creates new instance of the Java class (defined by <code>http://cyberborean.org/rdfbeans/1.0/bindingClass</code> property) and fill the properties with data from the RDF model. If a property holds a reference to another RDFBean, it results into cascade unmarshalling of related objects, thus restoring the original object model.</p>
<h2>Code</h2>
<ul>
<li><a href="http://cyberborean.org/files/rdfbeans/1.0/">RDFBeans JAR and source code</a></li>
<li><a href="http://cyberborean.org/files/rdfbeans/1.0/apidocs/">Javadocs</a></li>
</ul>
<p><strong>[Update: 2009-08-04]</strong></p>
<p>RDFBeans framework is released on SourceForge: <a href="http://rdfbeans.sourceforge.net/">http://rdfbeans.sourceforge.net</a>. The API has been changed, please check the <a href="http://rdfbeans.sourceforge.net/usage.html">documentation</a> and <a href="http://rdfbeans.sourceforge.net/apidocs/index.html">Javadocs</a> for details.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cyberborean.org/2009/02/06/simple-rdf-data-binding/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Compose key magic</title>
		<link>http://blog.cyberborean.org/2008/01/06/compose-key-magic</link>
		<comments>http://blog.cyberborean.org/2008/01/06/compose-key-magic#comments</comments>
		<pubDate>Sun, 06 Jan 2008 13:25:58 +0000</pubDate>
		<dc:creator>Alex Alishevskikh</dc:creator>
				<category><![CDATA[Howtos]]></category>
		<category><![CDATA[keyboard]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[unicode]]></category>

		<guid isPermaLink="false">http://cyberborean.wordpress.com/2008/01/06/compose-key-magic/</guid>
		<description><![CDATA[There are some amusing things in Linux which are hard to discover because they are invisible. Entering Unicode characters and sequences with a Compose key is one of those hidden features which can make user&#8217;s life much easier. How it works It&#8217;s simple and easy. You press and release a special key called &#8220;Compose&#8221; (or, [...]]]></description>
			<content:encoded><![CDATA[<p>There are some amusing things in Linux which are hard to discover because they are invisible. Entering Unicode characters and sequences with a Compose key is one of those hidden features which can make user&#8217;s life much easier.</p>
<p><span id="more-197"></span></p>
<h3>How it works</h3>
<p>It&#8217;s simple and easy. You press and release a special key called &#8220;<a href="http://en.wikipedia.org/wiki/Compose_key">Compose</a>&#8221; (or, &#8220;Multi_key&#8221;) and then, two or three character keys &#8211; a mnemonic ASCII sequence identifies a Unicode character you want to see. For example, the sequence of letter keys &#8220;o&#8221; and &#8220;c&#8221; produces the copyright symbol (©) and it is much easier to remember than Unicode <a href="http://www.fileformat.info/info/unicode/char/00a9/index.htm">00A9</a>.</p>
<h3>Where is my Compose key?</h3>
<p>There is no Compose key defined in X.org by default. Before using it, you need to do some configuration to tell X which key you want to use as a Compose. Usually,  right &#8220;Win&#8221; (&#8220;Super&#8221;) key is a good choice.</p>
<p><img src="http://cyberborean.wordpress.com/files/2008/01/kdecompose.png" alt="kdecompose.png" align="right" />In KDE, open &#8220;Keyboard layout&#8221; configuration panel (Control Center → Regional &amp; Accessibility → Keyboard Layout) and select &#8220;Enable xkb options&#8221; checkbox on &#8220;Xkb options&#8221; tab. Then scroll the options list down to &#8220;Compose key position&#8221; section and select a checkbox for a key you want to use as a Compose.</p>
<p>Alternatively, you can edit <code>/etc/X11/Xorg.conf</code> (as a root) to add the line to the keyboard section:</p>
<pre>Option "XkbOptions"  "compose:rwin"</pre>
<p>After configuration is done, restart X (simply hit Ctrl+Alt+Backspace).</p>
<p>Note that you&#8217;ll need Unicode fonts installed (to see all exotic characters) and a default locale with UTF-8 support (e.g. en_US.UTF-8 for US English).  This seems to be the default in modern Linux distributions.</p>
<h3>Predefined characters</h3>
<h4>Diacritics, ligatures and currency symbols</h4>
<p>Entering extended latin letters with diacritic marks follows the pattern:</p>
<pre><strong>Compose <em>diacritic_character letter</em></strong></pre>
<p>The diacritic characters are:</p>
<ul>
<li><strong></strong><code>'</code> (apostrophe) ⇒ A letter with acute (Áá)</li>
<li><strong></strong><code>"</code> (double quote) ⇒ A letter with diaeresis (Ää)</li>
<li><strong><code>`</code></strong> (grave) ⇒ A letter with grave (Àà)</li>
<li><strong></strong><code>_</code> (underscore) ⇒ A letter with macron (Āā)</li>
<li><strong><code>^</code></strong> (circumflex) ⇒ A letter with circumflex (Ââ)</li>
<li><strong></strong><code>~</code> (tilde) ⇒ A letter with tilde (Ãã)</li>
<li><strong></strong><code>,</code> (comma) ⇒ A letter with cedilla (Çç)</li>
<li><strong></strong><code>.</code> (period) ⇒ A letter with dot above (Ȧȧ)</li>
<li><strong><code>!</code></strong> (exclamation) ⇒ A letter with  dot below (Ạạ)</li>
<li><strong><code>?</code></strong> (question) ⇒ A letter with hook (Ảả)</li>
<li><strong><code>/</code></strong> (slash), <code>-</code><strong></strong> (minus) ⇒ A letter with stroke (Øø, Đđ)</li>
<li><strong><code>;</code></strong> (semicolon) ⇒ A letter with ogonek (Ąą)</li>
<li><strong></strong><code>+</code> (plus) ⇒ A letter with horn (Ơơ)</li>
<li><strong></strong><code>=</code> (equals) ⇒ A letter with double acute (Őő)</li>
<li><strong><code>o</code></strong> ⇒ A letter with ring (Åå)</li>
<li><strong><code>c</code></strong> ⇒ A letter with caron (Ǎǎ)</li>
<li><strong><code>b</code></strong> ⇒ A letter with breve (Ăă)</li>
</ul>
<p>Some characters may be combined to create mixed diacritical marks, e.g. <code>Compose _ " a</code> produces ǟ (&#8216;a&#8217; with diaeresis and macron), and so on.</p>
<p>Other letters and ligatures:</p>
<ul>
<li><code>Compose A/a E/e</code> ⇒ Æ/æ</li>
<li><code>Compose O/o E/e</code> ⇒ Œ/œ</li>
<li><code>Compose T/t H/h</code> ⇒ Þ/þ</li>
<li><code>Compose N/n G/g</code> ⇒ Ŋ/ŋ</li>
<li><code>Compose s s</code> ⇒ ß</li>
<li><code>Compose e e</code> ⇒ ə</li>
</ul>
<p>Currency symbols:</p>
<ul>
<li><code>Compose c /</code> ⇒ ¢</li>
<li><code>Compose C =</code> ⇒ €</li>
<li><code>Compose L =</code> ⇒ ₤</li>
<li><code>Compose F r</code> ⇒ ₣</li>
<li><code>Compose Y =</code> ⇒ ¥</li>
<li><code>Compose o x</code> ⇒ ¤</li>
</ul>
<h4>Punctuation marks and other symbols</h4>
<p>Quotation marks:</p>
<ul>
<li><code>Compose , '</code> ⇒ ‚</li>
<li><code>Compose , "</code> ⇒ „</li>
<li><code>Compose &lt; '</code> ⇒ ‘</li>
<li><code>Compose &gt; '</code> ⇒ ’</li>
<li><code>Compose &lt; "</code> ⇒ “</li>
<li><code>Compose &gt; "</code> ⇒ ”</li>
<li><code>Compose &lt; &lt;</code> ⇒ «</li>
<li><code>Compose &gt; &gt;</code> ⇒ »</li>
<li><code>Compose . &lt;</code> ⇒ ‹</li>
<li><code>Compose . &gt;</code> ⇒ ›</li>
</ul>
<p>Others:</p>
<ul>
<li><code>Compose . .</code> ⇒ ·</li>
<li><code>Compose - - -</code> ⇒ — (em-dash)</li>
<li><code>Compose - - .</code> ⇒ – (en-dash)</li>
<li><code>Compose ? ?</code> ⇒ ¿</li>
<li><code>Compose ! !</code> ⇒ ¡</li>
<li><code>Compose + -</code> ⇒ ±</li>
<li><code>Compose : -</code> ⇒ ÷</li>
<li><code>Compose 1 2</code> ⇒ ½</li>
<li><code>Compose 1 4</code> ⇒ ¼</li>
<li><code>Compose 3 4</code> ⇒ ¾</li>
<li><code>Compose _ 0-9</code> ⇒ ₀ &#8211; ₉ (subscript digit)</li>
<li><code>Compose ^ 0-9</code> ⇒ ⁰ &#8211; ⁹ (superscript digit)</li>
<li><code>Compose ( 0-9 )</code> ⇒ ⓪ &#8211; ⑨ (circled digit)</li>
<li><code>Compose o c</code> ⇒ ©</li>
<li><code>Compose o r</code> ⇒ ®</li>
<li><code>Compose o o</code> ⇒ °</li>
<li><code>Compose o s</code> ⇒ §</li>
<li><code>Compose x x</code> ⇒ ×</li>
<li><code>Compose P P</code> ⇒ ¶</li>
<li><code>Compose T M</code> ⇒ ™</li>
<li><code>Compose m u</code> ⇒ µ</li>
<li><code>Compose % o</code> ⇒ ‰</li>
</ul>
<h3>Defining custom Compose sequences</h3>
<p>Default Compose sequences are defined in &#8216;<code>Compose</code>&#8216; text file in the current locale directory (<code>/usr/share/X11/locale/xxx</code>). This file contains the rules to define Compose keyboard sequences and corresponding Unicode characters:</p>
<pre># UTF-8 (Unicode) compose sequence
# David.Monniaux (at) ens.fr
#
# $XFree86: xc/nls/Compose/en_US.UTF-8,v 1.11 2004/01/06 13:14:04 pascal Exp $
...
&lt;Multi_key&gt; &lt;less&gt; &lt;less&gt;        	: "«"   guillemotleft # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
&lt;Multi_key&gt; &lt;greater&gt; &lt;greater&gt;  	: "»"   guillemotright # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
&lt;Multi_key&gt; &lt;less&gt; &lt;apostrophe&gt;  	: "‘"   U2018 # LEFT SINGLE QUOTATION MARK
...</pre>
<p>To define new Compose sequence, we should add another rule using the syntax:</p>
<pre>&lt;Multi_key&gt; &lt;<em>key1</em>&gt; [&lt;<em>key2</em>&gt; ...]   	: "<em>character</em>"</pre>
<p>For instance, for a smiley character (☺, Unicode <a href="http://www.fileformat.info/info/unicode/char/263a/index.htm">263A</a>), the rule could be</p>
<pre>&lt;Multi_key&gt; &lt;colon&gt; &lt;parenright&gt; : "☺"  # Compose : )</pre>
<p>There is a number of utilities (like KCharSelect in KDE) for to select the Unicode characters and insert them into the file via clipboard.</p>
<p>It is possible to add new rules just into this system file (if you are root), but it&#8217;s better to create &#8216;<code>.XCompose</code>&#8216; file in the user home directory:</p>
<pre># ~/.XCompose
# This file defines custom Compose sequence for Unicode characters 

# Import default rules from the system Compose file:
include "/usr/share/X11/locale/en_US.UTF-8/Compose"

&lt;Multi_key&gt; &lt;colon&gt; &lt;parenright&gt; : "☺" U263A   # Compose : )
&lt;Multi_key&gt; &lt;minus&gt; &lt;less&gt;   : "←"  U2190 # Compose - &lt;
&lt;Multi_key&gt; &lt;minus&gt; &lt;greater&gt; : "→" U2192 # Compose -&gt;
...</pre>
<p>You also can assign whole strings to the Compose sequences — for instance, syntax constructions of your favorite programming language or HTML tags:</p>
<pre>&lt;Multi_key&gt; &lt;less&gt; &lt;p&gt; : "&lt;p&gt;&lt;/p&gt;" # Compose &lt; p
&lt;Multi_key&gt; &lt;less&gt; &lt;a&gt; : "&lt;a href=""&gt;&lt;/a&gt;" # Compose &lt; a
...</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.cyberborean.org/2008/01/06/compose-key-magic/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Custom ClassLoaders: The Black Art of Java</title>
		<link>http://blog.cyberborean.org/2007/07/04/custom-classloaders-the-black-art-of-java</link>
		<comments>http://blog.cyberborean.org/2007/07/04/custom-classloaders-the-black-art-of-java#comments</comments>
		<pubDate>Wed, 04 Jul 2007 07:19:12 +0000</pubDate>
		<dc:creator>Alex Alishevskikh</dc:creator>
				<category><![CDATA[Essays]]></category>
		<category><![CDATA[Howtos]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://cyberborean.wordpress.com/2007/07/04/custom-classloaders-the-black-art-of-java/</guid>
		<description><![CDATA[Java is great platform for component development but there are some odd and counterintuitive things on the way. One of these hidden pitfalls waiting for a developer who is going to replace default system ClassLoader with a custom one. A common case when you might have an idea of using a custom ClassLoader is to [...]]]></description>
			<content:encoded><![CDATA[<p><em>Java is great platform for component development but there are some odd and counterintuitive things on the way. One of these hidden pitfalls waiting for a developer who is going to replace default system ClassLoader with a custom one.</em></p>
<p><span id="more-172"></span></p>
<p>A common case when you might have an idea of using a custom ClassLoader is to avoid the classpath issues using <code><a href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/URLClassLoader.html">URLClassLoader</a></code> for loading classes instead of the default one. Classpath is a list of locations (JAR-files or directories) where default ClassLoader is looking for the classes to load. Declaring Classpath explicitly (either with <code>CLASSPATH</code> environment variable, or as a command-line argument of Java virtual machine) is tedious and error-prone job and it works only in the case of monolithic, statically-linked applications with known set of libraries.</p>
<p>But imagine a complex component-based system with a number of replaceable modules (plug-ins). It is obvious that classpath for that system should be built automatically to reflect the configuration changes before each running. It is often  done with system-specific startup scripts which analyzes the modules configuration and generates an appropriate classpath before starting the application. However, this method has its own drawbacks &#8211; especially in the case of poor Microsoft systems as their rudimentary command interpreter makes this task hardly possible. And this is a way system-dependent, of course.</p>
<p><code>URLClassLoader</code>, from a distant point of view, looks like an elegant, simple and &#8220;100%-pure-java&#8221; solution for the classpath headache. It is instantiated with an array of locations (URL&#8217;s) so each class loaded with that ClassLoader will use this array as a classpath. An advantage is that the classpath can be generated on the fly, automatically by an application itself.</p>
<p>So, let&#8217;s see how it works. Imagine we have an application with main executable class <code>Foo</code> (in package <code>com.example.foo</code>) and a lot of other classes in different locations. We will develop an invocation wrapper for loading <code>Foo</code> using URLClassLoader with an array of locations, generated automatically:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">/*
 * FooInvoker.java
 */</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.example.foo</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.net.URL</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.net.URLClassLoader</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.lang.reflect.Method</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.lang.reflect.Modifier</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> FooInvoker <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">String</span> FOO_CLASS_NAME <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;com.example.foo.Foo&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">URL</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> classpathURLs <span style="color: #339933;">=</span> getClasspathURLs<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003399;">ClassLoader</span> loader <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">URLClassLoader</span><span style="color: #009900;">&#40;</span>classpathURLs<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">Class</span> fooClass <span style="color: #339933;">=</span> loader.<span style="color: #006633;">loadClass</span><span style="color: #009900;">&#40;</span>FOO_CLASS_NAME<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #003399;">Method</span> main <span style="color: #339933;">=</span> fooClass.<span style="color: #006633;">getMethod</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;main&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000000; font-weight: bold;">Class</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span>.<span style="color: #000000; font-weight: bold;">class</span>
            <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">int</span> modifiers <span style="color: #339933;">=</span> main.<span style="color: #006633;">getModifiers</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Modifier</span>.<span style="color: #006633;">isPublic</span><span style="color: #009900;">&#40;</span>modifiers<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #003399;">Modifier</span>.<span style="color: #006633;">isStatic</span><span style="color: #009900;">&#40;</span>modifiers<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                main.<span style="color: #006633;">invoke</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span>, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Object</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #666666; font-style: italic;">// In this example, we assume Foo.main() takes no</span>
                <span style="color: #666666; font-style: italic;">// command-line arguments</span>
            <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">NoSuchMethodException</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #003399;">System</span>.<span style="color: #006633;">err</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Error running class &quot;</span> <span style="color: #339933;">+</span> FOO_CLASS_NAME
                    <span style="color: #339933;">+</span> e.<span style="color: #006633;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">URL</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> getClasspathURLs<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">URL</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> urls <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">URL</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// Here we're looking for all project-related libraries</span>
        <span style="color: #666666; font-style: italic;">// and constructing the classpath array</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
        <span style="color: #000000; font-weight: bold;">return</span> urls<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Run it (assuming <code>Foo</code> and <code>FooInvoker</code> are packaged both into <code>foo.jar</code> file, which is the core library of our app):</p>
<pre>$ java -classpath ./foo.jar com.example.foo.FooInvoker</pre>
<p>Alas! Everything located outside the <code>foo.jar</code> (that is, the classpath set in JVM arguments) is failed to load. For instance, if <code>Foo</code> uses class <code>Bar</code> in it&#8217;s own <code>bar.jar</code> library, <code>Foo</code> will throw <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassNotFoundException.html"><code>ClassNotFoundException</code> </a> despite of the fact that <code>bar.jar</code> has been passed to <code>URLClassLoader</code> argument. It seems we have no progress at all &#8211; all classes are loaded from default JVM classpath as with the system ClassLoader.</p>
<p>Let&#8217;s do some debugging. Add this to <code>Foo.main()</code> code to see which ClassLoader loads <code>Foo</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Foo is loaded with: &quot;</span> <span style="color: #339933;">+</span>
                           Foo.<span style="color: #000000; font-weight: bold;">class</span>.<span style="color: #006633;">getClassLoader</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Instead of &#8220;<code>java.net.URLClassLoader</code>&#8221; in output (as we hoped), we will see:</p>
<pre><code>Foo is loaded with: sun.misc.Launcher$AppClassLoader</code></pre>
<p>This is the default system ClassLoader. We really have no progress &#8211; it seems our <code>URLClassLoader</code> simply does not come into play. Our code is right but it doesn&#8217;t work. Is it a Java bug? Should we give up? Or report to Sun?</p>
<p>Wait a minute. The problem is not in code but in how Java VM executes it. Let&#8217;s try a trick: change <code>FooInvoker.getClasspathURLs()</code> algorythm to include <code>foo.jar</code> path in the resulted array (to be passed to <code>URLClassLoader</code> among other locations) and compile <code>FooInvoker</code> as a separate class file (not inside the <code>foo.jar</code>). Then run it (no classpath is declared!):</p>
<pre><code>$ java com.example.foo.FooInvoker
...
Foo is loaded with: java.net.URLClassLoader
</code></pre>
<p>Voila! Our <code>URLClassLoader</code> has been used to load <code>Foo</code> as well as other classes, including those from locations in our dynamic classpath. It works! So what is happened?</p>
<p>In this case we found ourselves in one of the dark and odd Java territories ruled by the Masters of The Black Java Art (also known as the Heavy Java Geeks) who believe the programs should not behave as their author expects, but following the mysterious Rules instead. One of those Rules is called &#8220;ClassLoader Delegation Model&#8221; and it <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html">reads</a>:</p>
<blockquote><p> The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. When requested to find a class or resource, a ClassLoader instance will delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself.</p></blockquote>
<p>A parent of <code>URLClassLoader</code> is the default system ClassLoader (as we used single-argument constructor). When we tried to load <code>Foo</code> with an instance of <code>URLClassLoader</code>, it asked the parent if  the latter could load <code>Foo</code>. As <code>Foo</code> was in the default classpath, the system ClassLoader, of course, could. By this way, it took a position of a default ClassLoader in a chain of subsequent class invocations and left our <code>URLClassLoader</code> out of business.</p>
<p>When we moved <code>Foo</code> and everything out the default classpath, the system ClassLoader was not able to load anything (except <code>FooInvoker</code> itself). So, it had no chance to took precedence over our custom ClassLoader.</p>
<p>Well, if you like rules, there is another one:</p>
<p><strong>If you use custom ClassLoader, do not give the system one a chance to come into play.</strong></p>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cyberborean.org/2007/07/04/custom-classloaders-the-black-art-of-java/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How to make a shortcut for Memoranda in KDE</title>
		<link>http://blog.cyberborean.org/2007/05/17/how-to-make-a-shortcut-for-memoranda-in-kde</link>
		<comments>http://blog.cyberborean.org/2007/05/17/how-to-make-a-shortcut-for-memoranda-in-kde#comments</comments>
		<pubDate>Thu, 17 May 2007 22:49:20 +0000</pubDate>
		<dc:creator>Alex Alishevskikh</dc:creator>
				<category><![CDATA[Howtos]]></category>
		<category><![CDATA[desktop]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Memoranda]]></category>

		<guid isPermaLink="false">http://cyberborean.wordpress.com/2007/05/17/how-to-make-a-shortcut-for-memoranda-in-kde/</guid>
		<description><![CDATA[Because of its crossplatform nature (&#8220;run anywhere&#8221;), Memoranda has no default &#8220;installer&#8221; to be embedded into user&#8217;s desktop environment automatically. But it is pretty easy to integrate it into that environment. Let&#8217;s see how to do that in KDE case. We assuming Memoranda is already installed on your Linux system (that is, ZIP archive is [...]]]></description>
			<content:encoded><![CDATA[<p><em>Because of its crossplatform nature (&#8220;run anywhere&#8221;), Memoranda has no default &#8220;installer&#8221; to be embedded into user&#8217;s desktop environment automatically. But it is pretty easy to integrate it into that environment. Let&#8217;s see how to do that in KDE case.</em></p>
<p><span id="more-168"></span></p>
<p>We assuming Memoranda is already installed on your Linux system (that is, ZIP archive is unpacked) into, say, &#8220;/opt/memoranda&#8221; directory. To be sure that the executables have proper permissions, run:</p>
<pre>chmod 755 /opt/memoranda/memoranda.sh
chmod 755 /opt/memoranda/lib/kde/systray4jd</pre>
<h3>Creating a desktop shortcut</h3>
<ol>
<li>Right-click anywhere on your desktop, select &#8220;Create New-&gt;Link to application&#8230;&#8221; and enter &#8220;Memoranda&#8221;.</li>
<li>Go to &#8220;Application&#8221; tab and enter into the fields<br />
<strong>Command:</strong> /opt/memoranda/memoranda.sh<br />
<strong>Work path:</strong> /opt/memoranda</li>
<li>Go back to &#8220;General&#8221; tab and click the icon. In the icon dialog box select &#8220;Other icons&#8221;, &#8220;Browse&#8221; and point it to &#8216;/opt/memoranda/lib/icons/memoranda48x48.png&#8217;</li>
<li>Press &#8220;Ok&#8221;</li>
</ol>
<p>To put new shortcut into KDE panel also, simply drag-n-drop it from the desktop.</p>
<h3>Creating a menu item</h3>
<ol>
<li>Right click the desktop shortcut created before and select &#8220;Copy&#8221;</li>
<li>Open Konqueror and navigate to &#8220;/home/<em>you</em>/.kde/share/applnk&#8221; directory. Tip: if Konqueror does not display &#8220;.kde&#8221; directory, select &#8220;Show hidden files&#8221; in its &#8220;View&#8221; menu.</li>
<li>Create new subdirectory (say, &#8220;Utilites&#8221;, &#8220;Office&#8221; or &#8220;PIM&#8221;) or go into an existing one. These subdirectories are the sections of your K menu. Right click anywhere in this directory and select &#8220;Paste file&#8221;.</li>
</ol>
<p>Done.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cyberborean.org/2007/05/17/how-to-make-a-shortcut-for-memoranda-in-kde/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using &#8220;win-key&#8221; in KDE</title>
		<link>http://blog.cyberborean.org/2006/10/19/using-win-key-in-kde</link>
		<comments>http://blog.cyberborean.org/2006/10/19/using-win-key-in-kde#comments</comments>
		<pubDate>Thu, 19 Oct 2006 14:37:24 +0000</pubDate>
		<dc:creator>Alex Alishevskikh</dc:creator>
				<category><![CDATA[Howtos]]></category>
		<category><![CDATA[desktop]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[Usability]]></category>

		<guid isPermaLink="false">http://cyberborean.wordpress.com/2006/10/19/using-win-key-in-kde/</guid>
		<description><![CDATA[It is nearly impossible to buy a PC keyboard without a key with the flag icon, which is usually referred as a &#8220;Win-key&#8221;. It is, of course, a question if there are any logical reasons to stamp a particular private OS logo on a universal hardware, but I am not going to discuss it right [...]]]></description>
			<content:encoded><![CDATA[<p>It is nearly impossible to buy a PC keyboard without a key with the flag icon, which is usually referred as a &#8220;Win-key&#8221;.   It is, of course, a question if there are any logical reasons to stamp a particular private OS logo on a universal hardware, but I am not going to discuss it right now. Instead of that, let&#8217;s see how to use this additional key for improving Linux user productivity.<br />
<span id="more-142"></span></p>
<p>I have no idea what is it doing in Windows, but the greatest advantage of this key in KDE is that it does nothing by default. Also, this is a modifier key (like Shift, Ctrl or Alt), so it can be used for setting a lot of custom keyboard shortcuts. While the most of &#8220;Ctrl+&#8221; and &#8220;Alt+&#8221; combinations are usually reserved by applications, &#8220;Win+&#8221; is vacant and ideal for defining various global system shortcuts.</p>
<p>There is my experience of using Win-key combinations:</p>
<h3>&#8220;Win&#8221; is for the windows, I think</h3>
<p>The most of shortcuts are related to the windows and desktop management actions:</p>
<ul>
<li><strong>Win+Return</strong> maximizes a window and <strong>Ctrl+Win+Return</strong> makes it full-screen.</li>
<li><strong>Win+Backspace</strong> minimizes a window.</li>
<li><strong>Win+Esc</strong> closes a window.</li>
<li><strong>Win+Space</strong> shows desktop (minimizes all windows).</li>
<li><strong>Win+<em>number</em></strong> (<strong>Win+1</strong>, <strong>Win+2</strong>&#8230;) switches to the given desktop. Also, <strong>Win+Up/Down</strong> switches to the previous or next desktop (I use vertical desktop pager).</li>
<li><strong>Ctrl+Win+<em>number</em></strong> and <strong>Ctrl+Win+Up/Down</strong> moves active window to the specified desktop.</li>
<li><strong>Win+Menu</strong> shows a list of all windows on all desktops.</li>
</ul>
<h3>AmaroK</h3>
<p>Win-key in combination with additional numeric keypad (aka &#8220;grey keys&#8221;) is used for controlling AmaroK audioplayer.</p>
<ul>
<li><strong>Win+GrayInsert</strong> is for play/pause.</li>
<li><strong>Win+GrayPlus</strong> and <strong>Win+GrayMinus</strong> manage sound volume and <strong>Win+GrayMultiply</strong> mutes volume.</li>
<li><strong>Win+GrayLeft/Win+GrayRight</strong> switches the tracks</li>
</ul>
<h3>Launching the applications</h3>
<p>Combinations of the Win-key with alphabetic keys are used for quick launching the most needed applications and utilities. There are lot of them and it makes no sense to enumerate them here &#8211; every user has her own list of preferred software.</p>
<p>Win-key is a good thing, whatever a logo is there. Finally, everyone might put a penguin or K-gear sticker on it :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cyberborean.org/2006/10/19/using-win-key-in-kde/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting new mail onto the desktop</title>
		<link>http://blog.cyberborean.org/2006/09/12/getting-new-mail-onto-the-desktop</link>
		<comments>http://blog.cyberborean.org/2006/09/12/getting-new-mail-onto-the-desktop#comments</comments>
		<pubDate>Tue, 12 Sep 2006 15:24:56 +0000</pubDate>
		<dc:creator>Alex Alishevskikh</dc:creator>
				<category><![CDATA[Essays]]></category>
		<category><![CDATA[Howtos]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[desktop]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[PIM]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://cyberborean.wordpress.com/2006/09/12/getting-new-mail-onto-the-desktop/</guid>
		<description><![CDATA[I had nice last weekend gathering new harvest of apples, drinking fresh apple juice and playing with SuperKaramba widgets &#8211; a good opportunity to take a sort of &#8220;recreational programming&#8221;. Perhaps all modern KDE users know those nice resource eaters eye-candies which are living right on the desktop surface and displaying the clocks, calendars, weather [...]]]></description>
			<content:encoded><![CDATA[<p>I had nice last weekend gathering new harvest of apples, drinking fresh apple juice and playing with <a href="http://netdragon.sourceforge.net">SuperKaramba</a> widgets &#8211; a good opportunity to take a sort of &#8220;recreational programming&#8221;. Perhaps all modern KDE users know those nice <s>resource eaters</s> eye-candies which are living right on the desktop surface and displaying the clocks, calendars, weather forecasts, system monitors and so on.</p>
<p>Instead of developing some Yet Another Big Animated Clock, I decided to write something practical. What I&#8217;d like to have is a widget which would ask my e-mail client (<a href="http://kmail.kde.org">KMail</a>) for the headers of the latest unread messages to show them on the desktop.<br />
<span id="more-133"></span></p>
<p><img src="http://cyberborean.org/blog/wp-content/uploads/2006/09/skkmail.jpg" alt="skkmail.jpg" /></p>
<p>Two buttons in the top bar are for checking new mail from a server and for opening new message window. Clicking on the top bar somewhere else will open main KMail window.</p>
<p>SuperKaramba comes with a <a href="http://netdragon.sourceforge.net/api.html">Python API</a>, so everyone who is familiar with Pyton basics can write her own widget (aka &#8220;theme&#8221;) as a Python script. In my case, I wrote two scripts &#8211; one is for widget output and another as a simple KMail folder API wrapped around DCOP calls.</p>
<h3>Patching KMail</h3>
<p>There was a major problem &#8211; KMail DCOP interface had no a call to get unread message headers; only getting a number of them is possible. So I have had to dig into the KMail sourcecode (my current version is 1.9.4) for to add new function to FolderIFace interface (<code>folderIface.cpp</code>).</p>
<h4><code>kmail.diff:</code></h4>

<div class="wp_syntax"><div class="code"><pre class="diff" style="font-family:monospace;">diff kmail/folderIface.cpp kmail_patched/folderIface.cpp
<span style="color: #440088;">147a148,162</span>
<span style="color: #00b000;">&gt; QStringList</span>
<span style="color: #00b000;">&gt; FolderIface::unreadMessageHeaders<span style="">&#40;</span><span style="">&#41;</span></span>
<span style="color: #00b000;">&gt; <span style="">&#123;</span></span>
<span style="color: #00b000;">&gt;      QStringList msgs;</span>
<span style="color: #00b000;">&gt;      mFolder-&gt;open<span style="">&#40;</span><span style="">&#41;</span>;</span>
<span style="color: #00b000;">&gt;      for<span style="">&#40;</span> int i = <span style="">0</span>; i &amp;amp;lt; mFolder-&gt;count<span style="">&#40;</span><span style="">&#41;</span>; i++<span style="">&#41;</span> <span style="">&#123;</span></span>
<span style="color: #00b000;">&gt;          KMMsgBase *msg = mFolder-&gt;getMsgBase<span style="">&#40;</span>i<span style="">&#41;</span>;</span>
<span style="color: #00b000;">&gt; 	     if <span style="">&#40;</span>msg-&gt;isNew<span style="">&#40;</span><span style="">&#41;</span> || msg-&gt;isUnread<span style="">&#40;</span><span style="">&#41;</span><span style="">&#41;</span> <span style="">&#123;</span></span>
<span style="color: #00b000;">&gt; 	       msgs.append<span style="">&#40;</span>msg-&gt;fromStrip<span style="">&#40;</span><span style="">&#41;</span> + &quot;\\t&quot; + msg-&gt;subject<span style="">&#40;</span><span style="">&#41;</span> + &quot;\\t&quot; + msg-&gt;dateStr<span style="">&#40;</span><span style="">&#41;</span><span style="">&#41;</span>;</span>
<span style="color: #00b000;">&gt;          <span style="">&#125;</span></span>
<span style="color: #00b000;">&gt;      <span style="">&#125;</span></span>
<span style="color: #00b000;">&gt;      mFolder-&gt;close<span style="">&#40;</span><span style="">&#41;</span>;</span>
<span style="color: #00b000;">&gt;      return msgs;</span>
<span style="color: #00b000;">&gt; <span style="">&#125;</span></span>
<span style="color: #00b000;">&gt;</span>
diff kmail/folderIface.h kmail_patched/folderIface.h
<span style="color: #440088;">61c61,62</span>
<span style="color: #991111;">&lt;</span>
<span style="color: #888822;">---
<span style="color: #00b000;">&gt;     virtual QStringList unreadMessageHeaders<span style="">&#40;</span><span style="">&#41;</span>;</span></span>
<span style="color: #00b000;">&gt;</span></pre></div></div>

<p>After adding new function header to <code>folderIface.h</code> and rebuilding KMail, new DCOP call &#8220;<code>kmail FolderIface unreadMessageHeaders</code>&#8221; became available to get the list of message headers in format &#8220;From/Subject/Date&#8221; divided by tab characters (<code>\t</code>).</p>
<h3>Sourcecode</h3>
<h4><code>skkmail.py</code>:</h4>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> karamba
<span style="color: #ff7700;font-weight:bold;">import</span> kmail
&nbsp;
text = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
images = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
clickAreas = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Define widget area width here (height is adjusted automatically)</span>
s_width = <span style="color: #ff4500;">350</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># If an actual height is above this value, a widget area will be clipped</span>
maxHeight = <span style="color: #ff4500;">600</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Margins inside a widget area</span>
s_x = <span style="color: #ff4500;">10</span>
s_y = <span style="color: #ff4500;">10</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> _update<span style="color: black;">&#40;</span>widget<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">global</span> text, images, clickAreas, s_width, s_x, s_y
    x_gap = <span style="color: #ff4500;">10</span>
    y_gap = <span style="color: #ff4500;">4</span>
&nbsp;
    s_height = <span style="color: #ff4500;">14</span>
    s_col1 = <span style="color: black;">&#40;</span>s_width-x_gap<span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #ff4500;">0.66</span>
    s_col2 = s_width
    s_col3 = <span style="color: black;">&#40;</span>s_width-x_gap-<span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #ff4500;">0.33</span>
&nbsp;
    folderFont = <span style="color: #483d8b;">&quot;Franklin Gothic Medium&quot;</span>
    folderFontSize = <span style="color: #ff4500;">14</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> t <span style="color: #ff7700;font-weight:bold;">in</span> text:
        <span style="color: #ff7700;font-weight:bold;">try</span>:
          karamba.<span style="color: black;">deleteText</span><span style="color: black;">&#40;</span>widget, t<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span>:
          <span style="color: #ff7700;font-weight:bold;">pass</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> images:
        <span style="color: #ff7700;font-weight:bold;">try</span>:
          karamba.<span style="color: black;">deleteImage</span><span style="color: black;">&#40;</span>widget, i<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span>:
          <span style="color: #ff7700;font-weight:bold;">pass</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> c <span style="color: #ff7700;font-weight:bold;">in</span> clickAreas:
        <span style="color: #ff7700;font-weight:bold;">try</span>:
          karamba.<span style="color: black;">removeClickArea</span><span style="color: black;">&#40;</span>widget, c<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span>:
          <span style="color: #ff7700;font-weight:bold;">pass</span>
    text = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    images = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    clickAreas = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    folders = kmail.<span style="color: black;">getFolders</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    y = s_y + <span style="color: #ff4500;">25</span><span style="color: #66cc66;">;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> f <span style="color: #ff7700;font-weight:bold;">in</span> folders:
        msgs = f.<span style="color: black;">unreadMessages</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>msgs<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
            y0 = y
            t = karamba.<span style="color: black;">createText</span><span style="color: black;">&#40;</span>widget, s_x+<span style="color: #ff4500;">15</span>, y, s_width, s_height,
                f.<span style="color: black;">name</span>+<span style="color: #483d8b;">&quot; (&quot;</span>+<span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>msgs<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>+<span style="color: #483d8b;">&quot;)&quot;</span><span style="color: black;">&#41;</span>
            karamba.<span style="color: black;">changeTextFont</span><span style="color: black;">&#40;</span>widget, t, folderFont<span style="color: black;">&#41;</span>
            karamba.<span style="color: black;">changeTextSize</span><span style="color: black;">&#40;</span>widget, t, folderFontSize<span style="color: black;">&#41;</span>
            text.<span style="color: black;">append</span><span style="color: black;">&#40;</span>t<span style="color: black;">&#41;</span>
            images.<span style="color: black;">append</span><span style="color: black;">&#40;</span>karamba.<span style="color: black;">createImage</span><span style="color: black;">&#40;</span>widget, s_x-<span style="color: #ff4500;">10</span>, y, <span style="color: #483d8b;">&quot;icons/folder.png&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            y = y + s_height + y_gap<span style="color: #66cc66;">*</span><span style="color: #ff4500;">2</span> +<span style="color: #ff4500;">10</span>
            <span style="color: #ff7700;font-weight:bold;">for</span> m <span style="color: #ff7700;font-weight:bold;">in</span> msgs:
                t = karamba.<span style="color: black;">createText</span><span style="color: black;">&#40;</span>widget, s_x+<span style="color: #ff4500;">20</span>, y, s_col1, s_height, m<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
                text.<span style="color: black;">append</span><span style="color: black;">&#40;</span>t<span style="color: black;">&#41;</span>
                t = karamba.<span style="color: black;">createText</span><span style="color: black;">&#40;</span>widget, s_x, y+s_height, s_col2, s_height, m<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
                text.<span style="color: black;">append</span><span style="color: black;">&#40;</span>t<span style="color: black;">&#41;</span>
                t = karamba.<span style="color: black;">createText</span><span style="color: black;">&#40;</span>widget, s_x+<span style="color: #ff4500;">20</span>+s_col1+x_gap, y, s_col3, s_height, m<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
                karamba.<span style="color: black;">setTextAlign</span><span style="color: black;">&#40;</span>widget, t, <span style="color: #483d8b;">&quot;RIGHT&quot;</span><span style="color: black;">&#41;</span>
                text.<span style="color: black;">append</span><span style="color: black;">&#40;</span>t<span style="color: black;">&#41;</span>
                images.<span style="color: black;">append</span><span style="color: black;">&#40;</span>karamba.<span style="color: black;">createImage</span><span style="color: black;">&#40;</span>widget, s_x, y, <span style="color: #483d8b;">&quot;icons/mail.png&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
                y = y + s_height<span style="color: #66cc66;">*</span><span style="color: #ff4500;">2</span> + y_gap<span style="color: #66cc66;">*</span><span style="color: #ff4500;">2</span>
            clickAreas.<span style="color: black;">append</span><span style="color: black;">&#40;</span>karamba.<span style="color: black;">createClickArea</span><span style="color: black;">&#40;</span>widget, s_x-<span style="color: #ff4500;">10</span>, y0, s_width, y-y0,
                <span style="color: #483d8b;">&quot;dcop kmail KMailIface selectFolder &quot;</span>+f.<span style="color: black;">path</span>+<span style="color: #483d8b;">&quot; &amp;&amp; kmail&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            y = y + y_gap<span style="color: #66cc66;">*</span><span style="color: #ff4500;">2</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>y <span style="color: #66cc66;">&lt;</span> maxHeight - <span style="color: #ff4500;">20</span><span style="color: black;">&#41;</span>:
        karamba.<span style="color: black;">resizeWidget</span><span style="color: black;">&#40;</span>widget, s_width+s_x<span style="color: #66cc66;">*</span><span style="color: #ff4500;">2</span>, y+<span style="color: #ff4500;">20</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#this is called when you widget is initialized</span>
<span style="color: #ff7700;font-weight:bold;">def</span> initWidget<span style="color: black;">&#40;</span>widget<span style="color: black;">&#41;</span>:
    bgImage = karamba.<span style="color: black;">createBackgroundImage</span><span style="color: black;">&#40;</span>widget, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">5</span>, <span style="color: #483d8b;">&quot;icons/bg.png&quot;</span><span style="color: black;">&#41;</span>
    karamba.<span style="color: black;">resizeImage</span><span style="color: black;">&#40;</span>widget, bgImage, s_width+s_x<span style="color: #66cc66;">*</span><span style="color: #ff4500;">2</span>, <span style="color: #ff4500;">20</span><span style="color: black;">&#41;</span>
    logo = karamba.<span style="color: black;">createImage</span><span style="color: black;">&#40;</span>widget, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span>, <span style="color: #483d8b;">&quot;icons/kmail.png&quot;</span><span style="color: black;">&#41;</span>
    t = karamba.<span style="color: black;">createText</span><span style="color: black;">&#40;</span>widget, <span style="color: #ff4500;">35</span>, <span style="color: #ff4500;">5</span>, <span style="color: #ff4500;">100</span>, <span style="color: #ff4500;">20</span>, <span style="color: #483d8b;">&quot;new mail&quot;</span><span style="color: black;">&#41;</span>
    karamba.<span style="color: black;">changeTextFont</span><span style="color: black;">&#40;</span>widget, t, <span style="color: #483d8b;">&quot;Franklin Gothic Medium&quot;</span><span style="color: black;">&#41;</span>
    karamba.<span style="color: black;">changeTextSize</span><span style="color: black;">&#40;</span>widget, t, <span style="color: #ff4500;">16</span><span style="color: black;">&#41;</span>
    karamba.<span style="color: black;">createClickArea</span><span style="color: black;">&#40;</span>widget, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">100</span>, <span style="color: #ff4500;">30</span>, <span style="color: #483d8b;">&quot;kmail&quot;</span><span style="color: black;">&#41;</span>
    karamba.<span style="color: black;">createImage</span><span style="color: black;">&#40;</span>widget, s_width+s_x<span style="color: #66cc66;">*</span><span style="color: #ff4500;">2</span>-<span style="color: #ff4500;">18</span>, <span style="color: #ff4500;">7</span>, <span style="color: #483d8b;">&quot;icons/mail_get.png&quot;</span><span style="color: black;">&#41;</span>
    karamba.<span style="color: black;">createClickArea</span><span style="color: black;">&#40;</span>widget, s_width+s_x<span style="color: #66cc66;">*</span><span style="color: #ff4500;">2</span>-<span style="color: #ff4500;">18</span>, <span style="color: #ff4500;">7</span>, <span style="color: #ff4500;">16</span>, <span style="color: #ff4500;">16</span>, <span style="color: #483d8b;">&quot;dcop kmail KMailIface checkMail&quot;</span><span style="color: black;">&#41;</span>
    karamba.<span style="color: black;">createImage</span><span style="color: black;">&#40;</span>widget, s_width+s_x<span style="color: #66cc66;">*</span><span style="color: #ff4500;">2</span>-<span style="color: #ff4500;">40</span>, <span style="color: #ff4500;">7</span>, <span style="color: #483d8b;">&quot;icons/mail_new.png&quot;</span><span style="color: black;">&#41;</span>
    karamba.<span style="color: black;">createClickArea</span><span style="color: black;">&#40;</span>widget, s_width+s_x<span style="color: #66cc66;">*</span><span style="color: #ff4500;">2</span>-<span style="color: #ff4500;">40</span>, <span style="color: #ff4500;">7</span>, <span style="color: #ff4500;">16</span>, <span style="color: #ff4500;">16</span>,
        <span style="color: #483d8b;">&quot;dcop kmail KMailIface openComposer '' '' '' '' '' ''&quot;</span><span style="color: black;">&#41;</span>
    _update<span style="color: black;">&#40;</span>widget<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#this is called everytime your widget is updated</span>
<span style="color: #808080; font-style: italic;">#the update inverval is specified in the .theme file</span>
<span style="color: #ff7700;font-weight:bold;">def</span> widgetUpdated<span style="color: black;">&#40;</span>widget<span style="color: black;">&#41;</span>:
    _update<span style="color: black;">&#40;</span>widget<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#This gets called everytime our widget is clicked.</span>
<span style="color: #808080; font-style: italic;"># Middle button click forces to check new mail</span>
<span style="color: #ff7700;font-weight:bold;">def</span> widgetClicked<span style="color: black;">&#40;</span>widget, x, y, button<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>button == <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>:
        kmail.<span style="color: black;">dcopCall</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;kmail KMailIface checkMail&quot;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<h4><code>kmail.py:</code></h4>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">subprocess</span>, <span style="color: #dc143c;">string</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> dcopCall<span style="color: black;">&#40;</span>call<span style="color: black;">&#41;</span>:
  <span style="color: #dc143c;">cmd</span> = <span style="color: #483d8b;">&quot;dcop &quot;</span>+call
  pipe = <span style="color: #dc143c;">subprocess</span>.<span style="color: black;">Popen</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">cmd</span>, shell=<span style="color: #008000;">True</span>, bufsize=<span style="color: #ff4500;">1024</span>, stdout=<span style="color: #dc143c;">subprocess</span>.<span style="color: black;">PIPE</span><span style="color: black;">&#41;</span>.<span style="color: black;">stdout</span>
  res = pipe.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  pipe.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">return</span> res
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Folder:
  path = <span style="color: #483d8b;">&quot;&quot;</span>
  name = <span style="color: #483d8b;">&quot;&quot;</span>
  unreadCount = <span style="color: #ff4500;">0</span>
  unreadMessages = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, path<span style="color: black;">&#41;</span>:
    dcopCall<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;kmail KMailIface getFolder &quot;</span>+path<span style="color: black;">&#41;</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">path</span> = path
    <span style="color: #008000;">self</span>.<span style="color: black;">unreadMessages</span> = <span style="color: #008000;">self</span>.<span style="color: black;">getUnreadMessages</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
  <span style="color: #ff7700;font-weight:bold;">def</span> getUnreadMessages<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
    r = dcopCall<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;kmail FolderIface unreadMessageHeaders&quot;</span><span style="color: black;">&#41;</span>
    ss = <span style="color: #dc143c;">string</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span>r, <span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>n&quot;</span><span style="color: black;">&#41;</span>
    msg = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> s <span style="color: #ff7700;font-weight:bold;">in</span> ss:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
            msg.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span>s, <span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>t&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    unreadCount = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>msg<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>unreadCount <span style="color: #66cc66;">&gt;</span> <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">name</span> = <span style="color: #dc143c;">string</span>.<span style="color: black;">strip</span><span style="color: black;">&#40;</span>dcopCall<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;kmail FolderIface displayName&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    msg.<span style="color: black;">reverse</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> msg
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> getFolders<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    r = dcopCall<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;kmail KMailIface folderList&quot;</span><span style="color: black;">&#41;</span>
    folders = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> f <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">string</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span>r, <span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>n&quot;</span><span style="color: black;">&#41;</span>:
        folders.<span style="color: black;">append</span><span style="color: black;">&#40;</span>Folder<span style="color: black;">&#40;</span>f<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> folders</pre></td></tr></table></div>

<h4><code>skkmail.theme:</code></h4>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># you can change initial widget position, area size and updatin interval (default = 1min)</span>
karamba x=<span style="color: #ff4500;">100</span> y=<span style="color: #ff4500;">100</span> w=<span style="color: #ff4500;">400</span> h=<span style="color: #ff4500;">200</span> interval=<span style="color: #ff4500;">60000</span>
defaultfont font=<span style="color: #483d8b;">&quot;Franklin Gothic Book&quot;</span> fontsize=<span style="color: #ff4500;">12</span> color=<span style="color: #ff4500;">230</span>,<span style="color: #ff4500;">230</span>,<span style="color: #ff4500;">230</span></pre></td></tr></table></div>

<p>All code above is <a href="http://www.gnu.org/licenses/gpl.html">GPL</a>&#8216;ed.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.cyberborean.org/2006/09/12/getting-new-mail-onto-the-desktop/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Tips &amp; Tricks:] Required text fields in Swing</title>
		<link>http://blog.cyberborean.org/2006/05/07/tips-tricks-required-text-fields-in-swing</link>
		<comments>http://blog.cyberborean.org/2006/05/07/tips-tricks-required-text-fields-in-swing#comments</comments>
		<pubDate>Sun, 07 May 2006 17:53:47 +0000</pubDate>
		<dc:creator>Alex Alishevskikh</dc:creator>
				<category><![CDATA[Howtos]]></category>
		<category><![CDATA[Coding]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[swing]]></category>
		<category><![CDATA[Usability]]></category>

		<guid isPermaLink="false">https://cyberborean.wordpress.com/2006/05/07/tips-tricks-required-text-fields-in-swing/</guid>
		<description><![CDATA[This article starts a &#8220;Tips &#38; Tricks&#8221; serie of &#8220;Chronicles&#8221; which is a result of my comeback to heavy coding. The posts in this serie are the bits of coding experience, a small inventions and solutions which every programmer does everyday. Read the latest Tips&#38;Tricks in Technology::Coding category. Swing dialogs by default have no idea [...]]]></description>
			<content:encoded><![CDATA[<p><em><br />
This article starts a &#8220;Tips &amp; Tricks&#8221; serie of &#8220;Chronicles&#8221; which is a result of my comeback to heavy coding. The posts in this serie are the bits of coding experience, a small inventions and solutions which every programmer does everyday. Read the latest Tips&amp;Tricks in <a href="http://cyberborean.wordpress.com/tag/technology/coding/">Technology::Coding</a> category.<br />
</em></p>
<p>Swing dialogs by default have no idea about &#8220;required&#8221; text fields, that is the fields which should be filled to perform a task. In this article I suggest a simple way how to automatically highlight the fields which have to be non-empty.</p>
<p><span id="more-97"></span></p>
<p>Our required fields will be highlighted when empty and switched to default look when a user enters a data into them. To track the changes of a field&#8217;s content we will use <code>DocumentEvent/DocumentListener</code> mechanism. <code>DocumentEvent</code>&#8216;s are generated by underlying <code>Document</code> model when it is changed by some way. Listening to these events is more reliable way than tracking the user actions (such as key pressings) directly, because it is guaranteed that any content change (including possible changes made by program itself, pasting the clipboard content from a context menu etc) will be monitored.</p>
<p>To listen these events, we should create an implementation of <code>DocumentListener</code> interface:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.swing.BorderFactory</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.swing.border.Border</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.swing.event.*</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.swing.text.JTextComponent</span><span style="color: #339933;">;</span>
...
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> HighlightListener <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">DocumentListener</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #003399;">JTextComponent</span> comp <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">Border</span> defaultBorder <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">Border</span> highlightBorder <span style="color: #339933;">=</span>
            <span style="color: #003399;">BorderFactory</span>.<span style="color: #006633;">createLineBorder</span><span style="color: #009900;">&#40;</span>java.<span style="color: #006633;">awt</span>.<span style="color: #003399;">Color</span>.<span style="color: #006633;">ORANGE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> HighlightListener<span style="color: #009900;">&#40;</span><span style="color: #003399;">JTextComponent</span> jtc<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        comp <span style="color: #339933;">=</span> jtc<span style="color: #339933;">;</span>
        defaultBorder <span style="color: #339933;">=</span> comp.<span style="color: #006633;">getBorder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// Adding this listener to a specified component:</span>
        comp.<span style="color: #006633;">getDocument</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">addDocumentListener</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// Highlight if empty:</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">maybeHighlight</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> insertUpdate<span style="color: #009900;">&#40;</span><span style="color: #003399;">DocumentEvent</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        maybeHighlight<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> removeUpdate<span style="color: #009900;">&#40;</span><span style="color: #003399;">DocumentEvent</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        maybeHighlight<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> changedUpdate<span style="color: #009900;">&#40;</span><span style="color: #003399;">DocumentEvent</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        maybeHighlight<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> maybeHighlight<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>comp.<span style="color: #006633;">getText</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;</span>gt<span style="color: #339933;">;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span>
            <span style="color: #666666; font-style: italic;">// if a field is non-empty, switch it to default look</span>
            comp.<span style="color: #006633;">setBorder</span><span style="color: #009900;">&#40;</span>defaultBorder<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">else</span>
            <span style="color: #666666; font-style: italic;">// if a field is empty, highlight it</span>
            comp.<span style="color: #006633;">setBorder</span><span style="color: #009900;">&#40;</span>highlightBorder<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// ... more actions</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>To add a highlighting functionality to a text component we should simply instantiate our <code>HighlightListener</code> with this component:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">...
<span style="color: #003399;">JTextField</span> myField <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">JTextField</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">new</span> HighlightListener<span style="color: #009900;">&#40;</span>myField<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
...</pre></div></div>

<p>Note that <code>HighlightListener</code> constructor is parametrized with <code>JTextComponent</code> class, so it can work with any children (<code>JEditorPane</code>, <code>JTextArea</code>), not only with <code>JTextField</code>.</p>
<p>Our <code>HighlightListener</code> monitors the updates of a component document model and checks if the text is empty or not. If it is empty, it will be highlighted by adding a thin orange border:</p>
<p><img src="http://cyberborean.org/blog/wp-content/uploads/2006/05/reqfield.png" /></p>
<p>Otherwise, the border will be reverted to its default look.</p>
<p>The code of <code>HighlightListener</code> can be customized for:</p>
<ul>
<li>Another highlighting method</li>
<li>Additional highlighting conditions &#8211; e.g. we can check the content against a regular expression for required input format (valid email adresses for instance)</li>
<li>Additional actions &#8211; e.g. to enable/disable the &#8220;OK&#8221; dialog button if required data is not entered.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.cyberborean.org/2006/05/07/tips-tricks-required-text-fields-in-swing/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

