tag:blogger.com,1999:blog-8319197872100153642024-03-13T02:49:14.189+02:00D.EVunsorted bits of software developmentPetar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.comBlogger37125tag:blogger.com,1999:blog-831919787210015364.post-84195057755392523992016-03-19T18:05:00.001+02:002016-03-21T22:01:55.483+02:00Ubuntu cannot mount /boot/efi<div dir="ltr" style="text-align: left;" trbidi="on">
Yesterday all of a sudden Ubuntu (14.04) refused to boot with a strange message that it could not mount /boot/efi.<br />
<br />
Running fsck from GRUB (Advanced menu) revealed this error<br />
<div style="margin-bottom: 0.8em; max-width: 45em; padding: 0px; width: auto;">
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">mount: wrong fs type, bad option, bad superblock on /dev/sdb1,<br /> missing codepage or helper program, or other error<br /> In some cases useful info is found in syslog - try<br /> dmesg | tail or so<br /><br />mountall: mount /boot/efi [771] terminated with status 32<br />mountall: filesystem could not be mounted: /boot/efi</span><br />
<br />
Opened root shell and tried to find the boot partition</div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"># parted</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">GNU Parted 2.3</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">Using /dev/sda</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">Welcome to GNU Parted! Type 'help' to view a list of commands.</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">(parted) print devices </span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">/dev/sda (1000GB)</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">/dev/sdb (120GB)</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">(parted) select /dev/sdb</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">Using /dev/sdb</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">(parted) print </span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">Model: ATA Samsung SSD 840 (scsi)</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">Disk /dev/sdb: 120GB</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">Sector size (logical/physical): 512B/512B</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">Partition Table: gpt</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">Number Start End Size File system Name Flags</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 1 1049kB 538MB 537MB fat32 boot</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 2 538MB 112GB 111GB ext4</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> 3 112GB 120GB 8466MB linux-swap(v1)</span><br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
Ok, so the boot partition is #1 on /dev/sdb, i.e. /dev/sdb1<br />
Tried to mount it manually<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">mount /dev/sdb1 /boot/efi</span><br />
<br />
Same error as above<br />
Ok, let's see the syslog as suggested in the message<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">dmesg | tail</span><br />
<br />
New error message<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">FAT-fs (sdb1): IO charset iso8859-1 not found</span><br />
<br />
Searching for this error found <a href="http://askubuntu.com/questions/571643/restore-boot-efi" target="_blank">this post</a> that suggested it is a problem with the dependency database.<br />
Tried running this as suggested in the post<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">sudo modprobe nls_iso8859-1</span><br />
<br />
but it complained that it could not load /lib/modules/3.13.0-83-generic/modules.dep.bin. This file existed but it was empty. But the file of the same name was non-empty in an older kernel directory.<br />
<br />
So back in GRUB and <b>selected the previous kernel version and Ubuntu booted normally</b>.<br />
Then tried this in an attempt to fix the package database<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">sudo apt-get check</span><br />
<br />
It complained with some error and suggested the following command<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">sudo dpkg --configure -a</span><br />
<br />
This finally fixed the issue. Afterwards Ubuntu booted normally with the latest kernel.<br />
Still not clear what caused this glitch. Didn't run any upgrades or so before it.<br />
Luckily it resolved without reinstall.<br />
<br />
<br /></div>
Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com2tag:blogger.com,1999:blog-831919787210015364.post-62263604309178368732015-11-10T01:46:00.000+02:002015-11-12T21:23:25.195+02:00Include mock<div dir="ltr" style="text-align: left;" trbidi="on">
Although recently I write mostly in (server side) JavaScript, I still have to return to my old C++ project once in a while. The other day I got notified that one of our integration tests will stop working due to changes in the database layer. It was testing a fix for a crash caused by inconsistent data coming from the db. So this integration test was trying to reproduce the situation by manipulating the data in the db. Actually reproducing such special cases with an integration test might be very difficult and unit tests are usually a better tool for this task. In the end I wanted to test some safety checks in our code, not an end to end scenario.<br />
<br />
Still the code under test was a big and hairy lump of C++ code with many hard-wired dependencies. It certainly was not written with testability in mind. While looking around for mocking solutions in C++, I came across the <a href="http://www.informit.com/articles/article.aspx?p=359417&seqNum=3" target="_blank">section about testing</a> from Michael Feathers' book <i>Working Effectively with Legacy Code</i>. He describes several approaches to mocking in C/C++, as he calls them <i>seams</i>. I was most impressed by the preprocessing seams. As Michael says, the preprocessor in C/C++ is kind of compensation for its stiffness compared to dynamic languages. It turns out the preprocessing seams are very powerful. You can take a C/C++ source file and compile it in a different environment thus making it do something very different.<br />
<br />
So inspired by preprocessing seams I derived my own <b>mocking approach in C/C++ that allows mocking of any function or class (even static, global and non-virtual) without changing the source file where these are called</b>.<br />
<br />
Here is the overall structure of a test file:<br />
<ol style="text-align: left;">
<li>Disable the original header that defines the dependency to be mocked using <a href="https://en.wikipedia.org/wiki/Include_guard" target="_blank">include guards</a></li>
<li>Provide alternative/mock definition of that dependency</li>
<li>#include the source file to be tested</li>
<li>Write the tests</li>
</ol>
Let's see a simple example.<br />
First, the header that defines the dependency that we want to mock.<br />
Notice that this header uses include guards.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">store.h</span><br />
<!-- store.h -->
<br />
<div style="background: #f0f0f0; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #007020;">#ifndef STORE_H</span>
<span style="color: #007020;">#define STORE_H</span>
<span style="color: #007020; font-weight: bold;">class</span> <span style="color: #0e84b5; font-weight: bold;">Connection</span>;
<span style="color: #007020; font-weight: bold;">class</span> <span style="color: #0e84b5; font-weight: bold;">Store</span>
{
<span style="color: #002070; font-weight: bold;">public:</span>
Store(Conection<span style="color: #666666;">&</span> conn);
<span style="color: #60a0b0; font-style: italic;">//...</span>
<span style="color: #007020; font-weight: bold;">const</span> <span style="color: #902000;">char</span><span style="color: #666666;">*</span> <span style="color: #06287e;">fetch</span>(<span style="color: #007020; font-weight: bold;">const</span> <span style="color: #902000;">char</span><span style="color: #666666;">*</span> query);
<span style="color: #902000;">void</span> <span style="color: #06287e;">store</span>(<span style="color: #007020; font-weight: bold;">const</span> <span style="color: #902000;">char</span><span style="color: #666666;">*</span> data);
<span style="color: #60a0b0; font-style: italic;">//...</span>
};
<span style="color: #007020;">#endif </span><span style="color: #60a0b0; font-style: italic;">// STORE_H</span>
</pre>
</div>
<br />
Next, the code that we want to test.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">consumer.cpp</span><br />
<div style="background: #f0f0f0; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #007020;">#include <string.h></span>
<span style="color: #007020;">#include "store.h"</span>
<span style="color: #902000;">int</span> <span style="color: #06287e;">measure</span>(Store<span style="color: #666666;">&</span> store, <span style="color: #007020; font-weight: bold;">const</span> <span style="color: #902000;">char</span><span style="color: #666666;">*</span> query)
{
<span style="color: #007020; font-weight: bold;">const</span> <span style="color: #902000;">char</span><span style="color: #666666;">*</span> v <span style="color: #666666;">=</span> store.fetch(query);
<span style="color: #007020; font-weight: bold;">return</span> strlen(v);
}
</pre>
</div>
<br />
And now the test.<br />
We want to mock <span style="font-family: "courier new" , "courier" , monospace;">Store</span>. To do this, we disable the original header by defining its include guard <span style="font-family: "courier new" , "courier" , monospace;">STORE_H</span>. Then we provide our mock implementation. Note the mock does not need to be compatible to the original class. We just need to provide the minimum so that the code under test can compile and execute. So we implement only the methods used during the test.<br />
Then we include the code to be tested <span style="font-family: "courier new" , "courier" , monospace;">consumer.cpp</span> so it will compile in our mocked environment.<br />
Finally, we run our test.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">test.cpp</span><br />
<div style="background: #f0f0f0; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #007020;">#include <iostream></span>
<span style="color: #007020;">#include <cassert></span>
<span style="color: #007020; font-weight: bold;">using</span> <span style="color: #007020; font-weight: bold;">namespace</span> std;
<span style="color: #007020;">#define STORE_H</span>
<span style="color: #007020; font-weight: bold;">class</span> <span style="color: #0e84b5; font-weight: bold;">Store</span>
{
<span style="color: #002070; font-weight: bold;">public:</span>
<span style="color: #007020; font-weight: bold;">const</span> <span style="color: #902000;">char</span><span style="color: #666666;">*</span> fetch(<span style="color: #007020; font-weight: bold;">const</span> <span style="color: #902000;">char</span><span style="color: #666666;">*</span> query)
{
<span style="color: #007020; font-weight: bold;">return</span> <span style="color: #4070a0;">"ola"</span>;
}
};
<span style="color: #007020;">#include "consumer.cpp"</span>
<span style="color: #902000;">int</span> <span style="color: #06287e;">main</span>(<span style="color: #902000;">int</span> argc, <span style="color: #902000;">char</span> <span style="color: #666666;">*</span>argv[])
{
Store mock_store;
assert(measure(mock_store, <span style="color: #4070a0;">"query"</span>) <span style="color: #666666;">==</span> <span style="color: #40a070;">3</span>);
cout <span style="color: #666666;"><<</span> <span style="color: #4070a0;">"OK"</span> <span style="color: #666666;"><<</span> endl;
}
</pre>
</div>
<br />
With this approach all the code related to the test is in one place. You don't need to tweak any additional compiler/linker configurations. Also notice that we did not change the original code <span style="font-family: "courier new" , "courier" , monospace;">consumer.cpp</span>, still we changed its behavior by compiling it in a mock environment.<br />
<br />
Also described briefly this technique on <a href="http://stackoverflow.com/a/33679515/2091399" target="_blank">SO</a>.</div>
Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-83877789726173512982015-03-22T22:44:00.000+02:002015-03-22T22:44:34.067+02:00Checking out GitHub pull requests locally<div dir="ltr" style="text-align: left;" trbidi="on">
When working with GitHub you often need to checkout a pull request (PR) locally so you can load it in your favorite tools and run/test it.<br />
<br />
<a href="https://help.github.com/articles/checking-out-pull-requests-locally/" target="_blank">GitHub help</a> suggests you can use a command similar to:<br />
<div>
<br /></div>
<div>
<pre class="command-line" style="-webkit-background-clip: padding-box; -webkit-font-smoothing: auto; background-clip: padding-box; background-color: #333333; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 2px solid rgb(221, 221, 221); color: white; font-family: Monaco, 'DejaVu Sans Mono', 'Courier New', monospace; font-size: 13px; font-stretch: inherit; line-height: inherit; margin-bottom: 10px; margin-top: 10px; overflow: auto; padding: 10px; vertical-align: baseline;"><span class="command" style="border: 0px; font-family: inherit; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline; white-space: pre-wrap;">git fetch origin pull/<em style="border: 0px; color: #f9fe64; font-family: inherit; font-size: inherit; font-stretch: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;">ID</em>/head && git checkout FETCH_HEAD</span></pre>
(here <i>ID</i> is the number of the pull request)<br />
<br />
While this will give you the original code of the PR, it might be different from what you will get if you actually merge the PR. The reason is that you might have parallel changes in your target (master) branch not yet merged in the PR. While you can do the merge also locally, it turns out this is not necessary as GitHub had alsready done it for you. All you need is to use this command instead:<br />
<br />
<pre class="command-line" style="-webkit-background-clip: padding-box; -webkit-font-smoothing: auto; background-clip: padding-box; background-color: #333333; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 2px solid rgb(221, 221, 221); color: white; font-family: Monaco, 'DejaVu Sans Mono', 'Courier New', monospace; font-size: 13px; font-stretch: inherit; line-height: inherit; margin-bottom: 10px; margin-top: 10px; overflow: auto; padding: 10px; vertical-align: baseline;"><span class="command" style="border: 0px; font-family: inherit; font-size: inherit; font-stretch: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline; white-space: pre-wrap;">git fetch origin pull/<em style="border: 0px; color: #f9fe64; font-family: inherit; font-size: inherit; font-stretch: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; margin: 0px; padding: 0px; vertical-align: baseline;">ID</em>/merge && git checkout FETCH_HEAD</span></pre>
(notice the difference in the refspec 'head' vs. 'merge')<br />
<br />
This will give you a merged version of the PR which contains all parallel commits in the target branch even those merged after the PR was created.<br />
<br /></div>
</div>
Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-85057502334358177162015-01-11T00:08:00.000+02:002015-01-11T00:16:49.754+02:00Rip audio CDs on LINUX<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuqvua21M81QciaUcyQJjDmw04lGw5xfBBHsShMwwmgQMDYxkd_S0COYWreOVov2SgPkcmmdR6WFlMbtYRVMoE99kVtLSWQ7nxAHjceFnMBRAGCvD28myrdDYujsy7hkx8uiLZP7K8BV9r/s1600/CD_Audio_icon.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuqvua21M81QciaUcyQJjDmw04lGw5xfBBHsShMwwmgQMDYxkd_S0COYWreOVov2SgPkcmmdR6WFlMbtYRVMoE99kVtLSWQ7nxAHjceFnMBRAGCvD28myrdDYujsy7hkx8uiLZP7K8BV9r/s1600/CD_Audio_icon.png" height="200" width="200" /></a></div>
<span style="font-family: Verdana, sans-serif;">I still use audio CDs sometimes. But they tend to get lost or damaged easily. So it is a good practice to convert them to MP3.</span><br />
<span style="font-family: Verdana, sans-serif;">So far I used Asunder for CD ripping. It is very easy to use ... when it works. But with some discs, usually lower quality CD-R, it just hangs right from the start. So I searched for another tool to rip audio CDs on LINUX.</span><br />
<span style="font-family: Verdana, sans-serif;">It turned out you can do this very quickly with two command line tools - cdparanoia & lame. As usual you can quickly install them on Ubuntu with a single command line:</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">$ sudo apt-get install cdparanoia lame</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span>
<span style="font-family: Verdana, sans-serif;">Assuming the CD is loaded in the CD drive, running this simple command will copy all audio tracks in WAV files in the current directory:</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">$ cdparanoia -B</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span>
<span style="font-family: Verdana, sans-serif;">Next to convert those WAV files to MP3, run this command:</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">$ ls -1 | xargs -L 1 lame --preset standard</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span>
<span style="font-family: Verdana, sans-serif;">This will compress the audio files about 10 times using VBR ~190kbps.</span><br />
<span style="font-family: Verdana, sans-serif;">If you are satisfied with the result, you can delete all WAV files:</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">$ rm *.wav</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span>
<span style="font-family: Verdana, sans-serif;">This will leave only MP3 files named like track04.cdda.mp3.</span><br />
<span style="font-family: Verdana, sans-serif;">Of course these tools have many more options so you can tweak them as much as you like. For example lame option --ta sets the artist and --tl the album in ID3 tags inside MP3 files.</span><br />
<span style="font-family: Verdana, sans-serif;">You can also script and automate this process as you see fit, but these are the tools that do the job nice and quickly.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span>
<span style="font-family: Verdana, sans-serif;">BTW did you know that "<i>disk" refers to magnetic storage while "disc" refers to optical storage</i>? See <a href="http://en.wikipedia.org/wiki/Spelling_of_disc" target="_blank">Wikipedia</a>.</span></div>
Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-83245461415357033322014-09-03T00:23:00.000+03:002014-09-03T00:23:53.162+03:00npm - first encounters<div dir="ltr" style="text-align: left;" trbidi="on">
Playing with node.js at work I hit an issue in the very beginning as I was unable to install any package using npm (the convenient package manager of node).<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">$ npm install nodemon</span><br />
<span style="font-family: Courier New, Courier, monospace;">npm ERR! network tunneling socket could not be established, cause=connect EINVAL</span><br />
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">npm ERR! network This is most likely not a problem with npm itself</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">npm ERR! network and is related to network connectivity.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">npm ERR! network In most cases you are behind a proxy or have bad network settings.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">npm ERR! network </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">npm ERR! network If you are behind a proxy, please make sure that the</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">npm ERR! network 'proxy' config is set properly. See: 'npm help config'</span></div>
</div>
<div>
<br /></div>
<div>
Ok, I really use a proxy so I run <span style="font-family: Courier New, Courier, monospace;">npm config edit</span> and uncomment these lines:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">; proxy=proxy:8080</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">; https-proxy=proxy:8080</span></div>
</div>
<div>
<br /></div>
<div>
Same result</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">$ npm install nodemon</span><br />
<span style="font-family: Courier New, Courier, monospace;">npm ERR! network tunneling socket could not be established, </span></div>
<div>
<br /></div>
<div>
The error EINVAL suggests that connect was called with an invalid argument. What that might be? Let's see the system calls of npm:</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">$ strace npm install nodemon 1> npm.strace 2>&1</span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">$ grep EINVAL npm.strace</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">ioctl(9, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7fff5f9a8330) = -1 EINVAL (Invalid argument)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">connect(10, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr("0.0.31.144")}, 16) = -1 EINVAL (Invalid argument)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">connect(10, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr("0.0.31.144")}, 16) = -1 EINVAL (Invalid argument)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">connect(10, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr("0.0.31.144")}, 16) = -1 EINVAL (Invalid argument)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">write(2, " tunneling socket could not be e"..., 65 tunneling socket could not be established, cause=connect EINVAL</span></div>
</div>
<div>
<br /></div>
<div>
Ahaa, we see 3 calls to <span style="font-family: Courier New, Courier, monospace;">connect</span> with IP 0.0.31.144 and port 443 (default HTTPS port) and all of these returned <span style="font-family: 'Courier New', Courier, monospace;">EINVAL (Invalid argument)</span><span style="font-family: inherit;">.</span></div>
<div>
<span style="font-family: inherit;">What is this strange IP? Asking Google for it, revealed this <a href="http://technolark.blogspot.com/2009/08/apt-get-cannot-initiate-connection-to.html" target="_blank">post</a> according to which, environment variable http_proxy should be given with a protocol, e.g.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">http_proxy=http://proxy:8080</span></div>
<div>
<br /></div>
<div>
So setting <span style="font-family: 'Courier New', Courier, monospace;">https-proxy=http://proxy:8080</span><span style="font-family: inherit;"> in npm config did solve the problem!</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">On my Linux both of these are set:</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">https_proxy=http://proxy:8080</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">HTTPS_PROXY=proxy:8080</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">and it seems npm takes the upper case variable to set the default values in npm config.</span></div>
<div>
<br /></div>
</div>
Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-43270810897409249232014-05-28T01:23:00.000+03:002014-05-28T23:49:27.396+03:00Dynamic auto-complete in Android<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
Auto-complete text input is very common in modern UI. It makes it easy to select an item from a large list or just provide some hint on matching items. Often the whole list of available items is not available, so you need to lookup matching items in some external source.<br />
In this example we use auto-complete to select a stock, similar to the search field on <a href="http://finance.yahoo.com/" target="_blank">finance.yahoo.com</a>.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjl3ANGxwE2AlHnM7TKG5vRjQ5Si5WZ_EJYDjphhDszG_FHC42rdkVZ607PFVqCgcWEo0jmVMflulGvdK6Drkk8CZFKy37A0ia5BZt0DusIO5fJPFGd8gdRZeVwO42gZRsILj3pVpgAsMBX/s1600/autocomplete-screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjl3ANGxwE2AlHnM7TKG5vRjQ5Si5WZ_EJYDjphhDszG_FHC42rdkVZ607PFVqCgcWEo0jmVMflulGvdK6Drkk8CZFKy37A0ia5BZt0DusIO5fJPFGd8gdRZeVwO42gZRsILj3pVpgAsMBX/s1600/autocomplete-screenshot.png" height="320" width="222" /></a></div>
<br />
Here we use a web API from Yahoo to lookup matching stocks, but you can use the same approach with any way of populating the auto-complete drop-down dynamically. For example you could search in a database.<br />
<br />
These are the major objects involved:<br />
<pre style="line-height: 16.25px;">AutoCompleteTextView -> Adapter -> Filter</pre>
<pre style="line-height: 16.25px;"></pre>
<pre style="line-height: 16.25px;"><span style="font-family: Courier New, Courier, monospace; line-height: normal; white-space: normal;"><b>
</b></span></pre>
<pre style="line-height: 16.25px;"><span style="font-family: Courier New, Courier, monospace; line-height: normal; white-space: normal;"><b>
</b></span></pre>
<pre style="line-height: 16.25px;"><span style="font-family: Courier New, Courier, monospace; line-height: normal; white-space: normal;"><b>android.widget.AutoCompleteTextView</b></span><span style="font-family: 'Times New Roman'; line-height: normal; white-space: normal;"> is the standard Android widget for this purpose. We will use it as it is but will implement custom Adpter and Filter.</span></pre>
<pre style="line-height: 16.25px;"><span style="font-family: 'Times New Roman'; line-height: normal; white-space: normal;">
</span></pre>
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto; word-wrap: normal;">
<pre style="line-height: 125%; margin: 0;"> symbolText = <span style="font-weight: bold;">new</span> AutoCompleteTextView(getActivity());
symbolText.setAdapter(<span style="font-weight: bold;">new</span> StockLookupAdapter(getActivity()));
</pre>
</div>
<br />
Here is our custom Adapter:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto; word-wrap: normal;">
<pre style="line-height: 125%; margin: 0;"><span style="font-weight: bold;">public</span> <span style="font-weight: bold;">class</span> <span style="font-weight: bold;">StockLookupAdapter</span> <span style="font-weight: bold;">extends</span>
ArrayAdapter<StockLookupAdapter.StockInfo> {
<span style="font-weight: bold;">private</span> <span style="font-weight: bold;">static</span> <span style="font-weight: bold;">final</span> String LOG_TAG = StockLookupAdapter.class
.getSimpleName();
<span style="font-weight: bold;">class</span> <span style="font-weight: bold;">StockInfo</span> {
<span style="font-weight: bold;">public</span> String symbol;
<span style="font-weight: bold;">public</span> String name;
<span style="font-weight: bold;">public</span> String exchange;
@Override
<span style="font-weight: bold;">public</span> String toString() {
<span style="font-style: italic;">// text to display in the auto-complete dropdown</span>
<span style="font-weight: bold;">return</span> symbol + <span style="font-style: italic;">" ("</span> + name + <span style="font-style: italic;">")"</span>;
}
}
<span style="font-weight: bold;">private</span> <span style="font-weight: bold;">final</span> StockLookupFilter filter = <span style="font-weight: bold;">new</span> StockLookupFilter();
<span style="font-weight: bold;">public</span> StockLookupAdapter(Context context) {
<span style="font-weight: bold;">super</span>(context, android.R.layout.simple_list_item_1);
}
@Override
<span style="font-weight: bold;">public</span> Filter getFilter() {
<span style="font-weight: bold;">return</span> filter;
}
<span style="font-weight: bold;">private</span> <span style="font-weight: bold;">class</span> <span style="font-weight: bold;">StockLookupFilter</span> <span style="font-weight: bold;">extends</span> Filter {
</pre>
<pre style="line-height: 125%; margin: 0;"> ...</pre>
<pre style="line-height: 125%; margin: 0;"> }</pre>
<pre style="line-height: 125%; margin: 0;">}</pre>
</div>
<br />
Here <span style="font-family: Courier New, Courier, monospace;">StockInfo</span> carries the data for each item in the drop down. Here we store the properties of each stock like symbol (a.k.a. ticker) and name. We override <span style="font-family: Courier New, Courier, monospace;">getFilter</span> to return the custom Filter - <span style="font-family: Courier New, Courier, monospace; line-height: 16.25px;">StockLookupFilter</span>. This is the essential part.<br />
Here is what <a href="http://developer.android.com/reference/android/widget/Filter.html">android.widget.Filter</a> docu says:<br />
<br />
<i>Filtering operations performed by calling filter(CharSequence) or filter(CharSequence, android.widget.Filter.FilterListener) are performed asynchronously. When these methods are called, a filtering request is posted in a request queue and processed later. Any call to one of these methods will cancel any previous non-executed filtering request.</i><br />
<br />
This is exactly what we need as calling a web API usually takes some time so we should not do it in the UI thread. Also the user may type faster than the web API can return the results. This could result in the hints shown in the drop-down lagging considerably behind the current text state. The queuing described above helps avoid this effect.<br />
<br />
So here is our custom filter (nested inside StockLookupAdapter):<br />
<div style="background: #ffffff; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto; word-wrap: normal;">
<pre style="line-height: 125%; margin: 0;"><span style="font-weight: bold;">private</span> <span style="font-weight: bold;">class</span> <span style="font-weight: bold;">StockLookupFilter</span> <span style="font-weight: bold;">extends</span> Filter {
<span style="font-style: italic;">// Invoked in a worker thread to filter the data according to the</span>
<span style="font-style: italic;">// constraint.</span>
@Override
<span style="font-weight: bold;">protected</span> FilterResults performFiltering(CharSequence constraint) {
FilterResults results = <span style="font-weight: bold;">new</span> FilterResults();
<span style="font-weight: bold;">if</span> (constraint != <span style="font-weight: bold;">null</span>) {
ArrayList<StockInfo> list = lookupStock(constraint);
results.values = list;
results.count = list.size();
}
<span style="font-weight: bold;">return</span> results;
}
<span style="font-weight: bold;">private</span> ArrayList<StockInfo> lookupStock(CharSequence constraint) {</pre>
<pre style="line-height: 125%; margin: 0;"> ...
}
<span style="font-style: italic;">// Invoked in the UI thread to publish the filtering results in the user</span>
<span style="font-style: italic;">// interface.</span>
@Override
<span style="font-weight: bold;">protected</span> <span style="font-weight: bold;">void</span> publishResults(CharSequence constraint,
FilterResults results) {
setNotifyOnChange(<span style="font-weight: bold;">false</span>);
clear();
<span style="font-weight: bold;">if</span> (results.count > 0) {
addAll((ArrayList<StockInfo>) results.values);
notifyDataSetChanged();
} <span style="font-weight: bold;">else</span> {
notifyDataSetInvalidated();
}
}
@Override
<span style="font-weight: bold;">public</span> CharSequence convertResultToString(Object resultValue) {
<span style="font-weight: bold;">if</span> (resultValue <span style="font-weight: bold;">instanceof</span> StockInfo) {
<span style="font-style: italic;">// text to set in the text view when an item from the dropdown</span>
<span style="font-style: italic;">// is selected</span>
<span style="font-weight: bold;">return</span> ((StockInfo) resultValue).symbol;
}
<span style="font-weight: bold;">return</span> <span style="font-weight: bold;">null</span>;
}
}</pre>
</div>
</div>
</div>
<br />
<span style="font-family: Courier New, Courier, monospace;">perfromFiltering</span> is executed in a background thread and it finds the items to be shown in the drop-down based on the current text in the text field.<br />
<span style="font-family: Courier New, Courier, monospace;">publishResults</span> is executed on the UI thread and it is given the FilterResults returned by <span style="font-family: 'Courier New', Courier, monospace;">perfromFiltering</span>. Here we just reset the ArrayAdapter contents and notify the UI to update.<br />
<span style="font-family: Courier New, Courier, monospace;">convertResultToString</span> returns the string to be substituted in the text field when a given item from the drop-down is selected. In our case we display both stock symbol and name in the drop-down but want only the symbol in the text field.<br />
<br />
So as we can see simple text navigation can be very efficient. Probably this is the reason why it is so popular these days. <br />
<br />
P.S.<br />
Still there is one glitch that irritates me. It seems part of the the drop-down is covered by the on-screen keyboard. If I try to close the keyboard, the drop-down is closed first.</div>
Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-80377574438839250412014-04-04T00:21:00.000+03:002014-04-04T00:21:37.605+03:00Does destruction change anything?<div dir="ltr" style="text-align: left;" trbidi="on">
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>class C{};</b></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><br /></b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// consider this</b></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><br /></b></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>void foo(const C* p)</b></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>{</b></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> delete p;</b></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>}</b></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><br /></b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// does it work? should it work?</b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// after all destroyng the object very much changes it </b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// and you are not allowed to change a const object, right?</b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// ...</b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// now consider this</b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// (you can substitute here auto_ptr </b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// with your favorite smart pointer)</b></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><br /></b></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>void foo(auto_ptr<const C> p) { }</b></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><br /></b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// is this possible at all?</b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// ...</b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// how about this</b></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><br /></b></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>void foo(const C x) { }</b></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><br /></b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// hmm... this is pretty common code</b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// if const objects exist (and we know they do) </b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// then they must come to an end somehow</b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b><br /></b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// so it is possible and completely normal to destroy </b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// a constant object and all of the above is valid code</b></span></div>
</div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b><br /></b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// so now my interpretation of const is this:</b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// if the object still exists, </b></span></div>
<div>
<span style="color: #38761d; font-family: Courier New, Courier, monospace;"><b>// its observable state should be the same as before</b></span></div>
<div>
<br /></div>
<div>
Based on <a href="http://stackoverflow.com/questions/755196/deleting-a-pointer-to-const-t-const" target="_blank">this post</a> on SO</div>
</div>
Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-90651470314553577412013-12-21T14:51:00.000+02:002013-12-21T14:51:53.534+02:00Back to native<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhecKynN6CgwZbw8MV1dxb1DpQBPda6uipM_s7yd3SaDHSXIK9J9o-vlsJcOz4L4l3eFHvSOZLtyf8wGAH1iJSmxpXYHT7t07gxISAL0vjrZavbx4qDooltWxwp7m2kBcrx65CUVVfjz2Ap/s1600/CPP.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhecKynN6CgwZbw8MV1dxb1DpQBPda6uipM_s7yd3SaDHSXIK9J9o-vlsJcOz4L4l3eFHvSOZLtyf8wGAH1iJSmxpXYHT7t07gxISAL0vjrZavbx4qDooltWxwp7m2kBcrx65CUVVfjz2Ap/s200/CPP.jpg" width="200" /></a></div>
Usually the end of the year is time to take a step back, reflect on the past and plan for the future. For me it is also a time for a change. After 9 years working in Java (SE) I will switch back to C++. So I'll use the opportunity to share some thoughts I have accumulated in recent years.<br />
Generally I avoid being a language zealot (like some of my colleagues ;). For me it is more important to create simple and beautiful solutions leveraging whatever technology is available.<br />
<br />
Some say <b>Java </b>tends to be too ceremonial and I would agree on that.<br />
Nowadays the industry has accepted that checked exceptions are not so useful after all.<br />
Proper resource management with all this exception handling feels very clumsy and is definitely inferior compared to the good old <a href="http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization" target="_blank">RIIA</a> mechanism available in C++.<br />
Some design mistakes from the yearly day of Java are still present for the sake of compatibility. These are things like decorator pattern overuse in stream handling and all these unnecessary methods in <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html" target="_blank">Object</a> most of which you rarely use but constantly pay the price for.<br />
<br />
It was interesting for me to see how <b>C++</b> has advanced for the last decade. I see there are many new and useful features <a href="http://en.wikipedia.org/wiki/C%2B%2B11" target="_blank">C++11</a>. For example <a href="http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions" target="_blank">lambdas</a> are now part of the standard while in Java they have been delayed for years and are still not present.<br />
The preprocessor and the necessity to use it has always been for me one of the major issues in C++. So I was hoping that this was addressed somehow in the recent evolution of the language. Alas! All these #include and #define directives and the involved text substitution without any awareness of the language feel like a stone age hack. And it is still there.<br />
Even before I started working in Java I thought it would be great if C++ could be compiled to some standard intermediate format. This could improve both compile-time and runtime performance. When you compile to machine instructions ahead-of-time (AOT) you rarely know the exact CPU where the code will run, so you cannot take advantage of new CPU features. I was glad to find recently that there is already a considerable effort in that direction - namely <a href="http://en.wikipedia.org/wiki/Llvm" target="_blank">LLVM</a> project even though it is not C/C++ specific.</div>
Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-72058912218778137482013-05-22T18:33:00.000+03:002013-05-22T18:33:39.045+03:00Java Serialization PerformanceThe Java program I work on in my day job maintains its data model in a tree-like structure of Java beans. The data volume is not big but still it is significant - about 500K property values in about 30K bean objects.<br />
To ensure our program can restart from point of failure we often have to save this data model to disk. We use custom XML serialization. As this takes quite some time (several seconds) I started researching different alternatives.<br />
<br />
It turned out that <b>JAXB</b> is not appropriate for the job as it does not cope well with cyclic dependencies and cross-references. It also requires adding a lot of annotations and our data model employs about 50 classes.<br />
<br />
Next I tried standard <b>Java object serialization</b> but it turned out to preform even worse - it saved the data model in <b>15s</b> in a <b>10MB</b> file.<br />
<br />
A quick search about Java serialization showed an open source library <a href="https://code.google.com/p/kryo/"><b>Kryo</b></a>. I was able to test it very easily as it requires no annotations and almost no code changes. Kryo turned out to be lightning fast! It saved the same data model in just <b>400ms</b> in a <b>5MB</b> file. At first I did not believe all our data was saved, so I loaded it back and compared it to the original data but there were no differences.<br />
One of the main reasons for this performance is that instead of reflection Kryo uses dynamic byte code generation via <a href="https://code.google.com/p/reflectasm/">ReflectASM</a>.<br />
I also found another project run by Nate - <a href="http://www.kickstarter.com/projects/esotericsoftware/spine">Spine</a> to be very interesting. It is related to game development. Obviously a very skilled developer.<br />
Kudos Nate, great job!<br />
<br />Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-11565572535280354852013-05-15T00:50:00.000+03:002013-05-15T00:50:20.958+03:00Batch convert MOV to MP4 in Ubuntu<span style="font-family: Verdana, sans-serif;">for i in *.MOV; do avconv -i $i -b:v 3000k ${i%.MOV}.MP4; done</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span>
<span style="font-family: Verdana, sans-serif;">Video: mjpeg -> libx264</span><br />
<span style="font-family: Verdana, sans-serif;">Audio: pcm_s16be -> libvo_aacenc</span><br />
<span style="font-family: Verdana, sans-serif;">Compression: 10 -> 1</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span>
<span style="font-family: Verdana, sans-serif;">These are video clips from my Panasonic photo camera</span>Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com1tag:blogger.com,1999:blog-831919787210015364.post-60616217210711328982013-05-08T21:38:00.001+03:002013-05-08T21:39:31.581+03:00mogrify or batch resize images in Ubuntu<pre><span style="font-size: large;">sudo apt-get install imagemagick
mogrify -resize 30% *.JPG</span>
</pre>
Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-44149639692615361142013-02-23T18:20:00.000+02:002013-02-23T18:20:08.021+02:00Function or methodLately I have been reading about Python. Here is an example that shows some interesting properties of functions and methods.<br />
Given this code in <b>methods.py</b><br />
<code>
<br />
def f(a):<br />
print a<br />
<br />
class C:<br />
def __init__(self, x):<br />
self.x = x<br />
<br />
def __str__(self):<br />
return "C(%d)" % self.x<br />
</code><br />
<div>
</div>
<br />
Let's try some statements in the Python console<br />
<br />
<code>
>>> from methods import *<br />
>>> f("Hello")<br />
Hello<br />
>>> c = C(5)<br />
>>> print c<br />
C(5)<br />
>>> c.f = f<br />
>>> c.f("bye")<br />
bye<br />
>>> C.g = f<br />
>>> c.g()<br />
C(5)<br />
>>> g = c.g<br />
>>> g()<br />
C(5)<br />
</code>
<br />
<br />
<br />Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com1tag:blogger.com,1999:blog-831919787210015364.post-60585698368874353942012-10-26T23:57:00.000+03:002013-02-23T17:57:11.262+02:00Beware of Premature GeneralizationWhen people start writing some new code they often feel so enthusiastic that they try to make it <i>reusable</i> right from the beginning. Or some do it out of some pretended sophistication. The end result is usually layers of unnecessary abstractions that are actually not used anywhere else. In the end such code takes more effort to write and more effort to maintain afterwards.<br />
The reality is that you cannot make something <i>reusable</i> if it is used in a single place/scenario. To make it reusable you do need at least two real use cases, so you can abstract the common traits. The more use cases you have, the better you can refine the abstraction.<br />
You may think you know what new use cases will come, but in reality these either don't come at all or are quite different from what you have expected.<br />
So don't do this, unless you can tell the future.<br />
<br />
I thought <i>premature generalization</i> would be a good term for such situations. Then after searching the net it turned out this term is well established already - <a href="http://c2.com/cgi/wiki?PrematureGeneralizationIsEvil">Premature Generalization Is Evil</a>. It is even listed as #1 in <a href="http://blogs.msdn.com/b/ericgu/archive/2006/08/03/687962.aspx">Seven deadly sins of programming</a>.Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-34796970636459348662012-08-30T10:17:00.000+03:002012-08-30T11:08:15.305+03:00Remove class inheritance from Java<h2>
Introduction</h2>
We often hear the advice that we should prefer composition over inheritance. Then naturally come the questions: <i>Are there valid cases at all to use inheritance? Is it possible that inheritance, one of the fundamental OOP principles, is actually an anti-pattern and unnecessary language feature?</i><br />
By <i>inheritance </i>here I mean only <i>class inheritance</i> and not interface extension.<br />
<br />
<h2>
Goodbye Class Inheritance</h2>
The most common reason for class inheritance found in practice is <b>code reuse</b>. When people realize they need some common code in two or more classes, they pull it up in a common base class (usually an <i>abstract</i> one). But what would you do if you need to reuse code from several other classes? There is no multiple inheritance in Java. The right way to reuse some common code is via <b>composition</b>, i.e. extract the common code in a separate class and use it via a reference.<br />
<br />
The next reason for inheritance is <b>method overriding</b>, i.e. <a href="http://en.wikipedia.org/wiki/Template_method_pattern">template method pattern</a>. When people realize they need some variability in behavior, they define a method for it (often <i>abstract</i>) and implement it in different ways in different subclasses. This is also wrong for several reasons. You cannot change the variable method implementation dynamically without changing the whole object. Also if you have several axes of variability, i.e. several abstract methods, how many subclasses do you need to cover all possible combinations? Again the right way to do that is via <b>composition</b>. Each independently variable part is extracted in a separate interface. Different implementations of these interfaces are injected from outisde, i.e. <a href="http://en.wikipedia.org/wiki/Strategy_pattern">strategy pattern</a>.<br />
<br />
Can you suggest cases where it is still best to use class inheritance? Post a comment.<br />
<br />
Generally, inheritance violates other OOP principles like encapsulation as it creates tight coupling between involved classes.<br />
<br />
The conclusion is that the availability of this feature (implementation inheritance) leads people into wrong designs. <b>So the Java language can be both improved and simplified if classes are not allowed to extend other classes.</b> Still an interface can extend other interfaces and a class can implement a number of interfaces.<br />
Removing this feature can simplify the language significantly. Additional language features can also be removed as they are no longer necessary.<br />
<ul>
<li><b><span style="font-family: "Courier New",Courier,monospace;">abstract</span> keyword is no longer necessary and can be removed</b>. Abstract coding can get you only abstract money. :)</li>
<li><b><span style="font-family: Courier New, Courier, monospace;">protected </span>keyword is no longer necessary and can be removed</b></li>
<li><b><span style="font-family: Courier New, Courier, monospace;">final </span>keyword on classes and methods
is no longer necessary</b></li>
<li>(Probably this list can be extended further. Drop your suggestions in the comments.)</li>
</ul>
So this is a nice example how taking away can improve the result, i.e.<i> less is more</i> principle. Or as Antoine de Saint-Exupery has put it<br />
<br />
<i>"Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away."</i><br />
<br />
<h2>
Welcome Auto-binding</h2>
Still when your class implements an interface you often do not write the code from scratch but want to reuse some existing implementation. As we saw already the proper way to do that is via composition. Something like this<br />
<br />
<div style="font-family: "Courier New",Courier,monospace;">
class A implements I</div>
<div style="font-family: "Courier New",Courier,monospace;">
{</div>
<div style="font-family: "Courier New",Courier,monospace;">
private I anI;</div>
<div style="font-family: "Courier New",Courier,monospace;">
... <br />
public void foo() { anI.foo(); }</div>
<div style="font-family: "Courier New",Courier,monospace;">
<div>
public void moo() { anI.moo(); }</div>
<div>
...</div>
}</div>
<br />
Unfortunately we have no way to tell that <span style="font-family: "Courier New",Courier,monospace;">anI</span> provides the implementation of interface <span style="font-family: "Courier New",Courier,monospace;">I</span>, so we have to implement all the methods of <span style="font-family: "Courier New",Courier,monospace;">I</span> in <span style="font-family: "Courier New",Courier,monospace;">A</span> just by delegating to <span style="font-family: "Courier New",Courier,monospace;">anI</span>. Boring boilerplate! This is where the second proposal for the language improvement kicks in. You can call it auto-wiring or auto-binding but it does just that, <b>specify that an interface is implemented by a specific class member</b>. Something like this:<br />
<br />
<div style="font-family: "Courier New",Courier,monospace;">
class A implements I <b>via</b> anI</div>
<div style="font-family: "Courier New",Courier,monospace;">
{</div>
<div style="font-family: "Courier New",Courier,monospace;">
private I anI;<br />
...
</div>
<div style="font-family: "Courier New",Courier,monospace;">
}</div>
<br />
The compiler can automatically generate the necessary delegation methods or an optimized implementation could even skip this overhead.<br />
<br />
If a class needs to customize the interface implementation it can still implement some of the interface methods, thus overriding these methods from the external implementation.<br />
<br />
Instead of a field also a method could be specified in case the interface implementation should be calculated dynamically. Something like this:<br />
<br />
<div style="font-family: 'Courier New', Courier, monospace;">
class A implements I <b>via</b> getI</div>
<div style="font-family: 'Courier New', Courier, monospace;">
{</div>
<div style="font-family: 'Courier New', Courier, monospace;">
private I getI() { ... }<br />
}</div>
<br class="Apple-interchange-newline" />
I find these two proposals for Java language improvement nicely complement each other and naturally lead developers in the right direction.<br />
Until these improvements are implemented in Java (version 15 probably :) you can try to avoid class inheritance in your code.Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com2tag:blogger.com,1999:blog-831919787210015364.post-26073487896460694922011-12-11T20:33:00.001+02:002012-08-30T08:57:46.643+03:00Ubuntu priceUbuntu costs no money but it costs time to search for solutions for various issues. And recent releases are full of issues most of which are regressions.<br />
The latest one is that file transfer over Bluetooth does not work - <a href="https://bugs.launchpad.net/ubuntu/+source/bluez/+bug/897995">Bug 897995</a>.<br />
<br />Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-62834988831041989552011-05-21T21:00:00.001+03:002011-05-21T21:00:40.174+03:00Natty Upgrade<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPBobQJbpwHVyNZCcOIvgtrtRvVDa7-Nhc0_O185UDJJyTfyTgzfdMnW2M6hniwELxpQhWC5xLq-E1D2sqYZhYq6zGB4WxSfmSAFHqI0btsox18zNG0Mk_oJR60lflRF8MvZch8V6Q1uNa/s1600/Ubuntu-11.04-Natty-Narwhal-Logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="133" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPBobQJbpwHVyNZCcOIvgtrtRvVDa7-Nhc0_O185UDJJyTfyTgzfdMnW2M6hniwELxpQhWC5xLq-E1D2sqYZhYq6zGB4WxSfmSAFHqI0btsox18zNG0Mk_oJR60lflRF8MvZch8V6Q1uNa/s200/Ubuntu-11.04-Natty-Narwhal-Logo.png" width="200" /></a></div>Finally upgraded to Ubuntu 11.04 Natty Narwhal. The upgrade went smooth. Download was faster than the actual package update. It is interesting to see the upgrade running while the old system is still usable. I guess they do the actual switch during the reboot. And Ubuntu upgrade takes only one reboot.<br />
<br />
But still there was a glitch after the upgrade. It said something that my display mode is not supported and switched it from 1920x1080 to 1024x768. Even if I try to switch it back, the image gets distorted. Then I noticed that Login screen used the right resolution and the same also for the other account on my PC. But when I login to my account the screen switches to 1024x768. Obviously it is some account-specific configuration. After couple of hours searching around I found the guilty file <b>~/.config/monitors.xml</b>. After deleting it and re-login the screen resolution is back to normal.<br />
<br />
Release 10.10 was pretty buggy. As <a href="http://www.tomshardware.com/">Tom</a> said once there seems to be a tradition of .10 releases being more unstable. I hope that 11.04 sticks to this tradition and is more reliable than the previous one.<a class="cssButton" href="javascript:void(0)" id="publishButton" onclick="if (this.className.indexOf("ubtn-disabled") == -1) {var e = document['postingForm'].publish;(e.length) ? e[0].click() : e.click(); if (window.event) window.event.cancelBubble = true; return false;}" target=""></a><br />
<div class="cssButtonOuter"><div class="cssButtonMiddle"><div class="cssButtonInner"><a class="cssButton" href="javascript:void(0)" id="publishButton" onclick="if (this.className.indexOf("ubtn-disabled") == -1) {var e = document['postingForm'].publish;(e.length) ? e[0].click() : e.click(); if (window.event) window.event.cancelBubble = true; return false;}" target=""><br />
</a></div></div></div>Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com1tag:blogger.com,1999:blog-831919787210015364.post-60991570974120784452011-04-10T16:30:00.000+03:002011-04-10T16:30:56.959+03:00Queries in SlingHere is how I use JCR queries in my .esp pages.<br />
The sample below lists all child nodes of the current node sorted by price property.<br />
<br />
<code><br />
<%<br />
var sql = "select * from [nt:base] where ischildnode('" + currentNode + "') order by price asc"; <br />
var query = currentSession.workspace.queryManager.createQuery(sql, Packages.javax.jcr.query.Query.JCR_SQL2);<br />
var result = query.execute();<br />
var iter = result.nodes;<br />
while (iter.hasNext()) {<br />
var node = iter.nextNode();<br />
%><br />
<br />
// render each node from the result<br />
<br />
<% } %><br />
</code><br />
<br />
Notice that when a Node is converted to string its path is used.<br />
Also here you can see how Packages object is used to access static members of Java classes. This is a Rhino feature. You can read more about it <a href="http://www.mozilla.org/rhino/ScriptingJava.html">here</a>.Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-74429885936389391662011-04-10T15:29:00.001+03:002011-04-10T15:31:31.741+03:00Resizing windows in UbuntuA major usability paint point in Ubuntu's default theme is that it is very difficult to grab the window border to resize it. The reason is that the borders are very thin, I think just one pixel.<br />
So I have been using Alt-F8 shortcut (see System > Preferences > Keyboard Shortcuts) to resize windows. But this is not very convenient either since you can resize in only one direction. To resize in another direction you have to press Alt-F8 again. Also the direction is chosen from the initial mouse movement after Alt-F8. Well, just try it.<br />
Now I got irritated by this obvious malfunction and did a quick search and found this <a href="http://askubuntu.com/questions/4109/how-do-i-increase-resize-margin-on-windows">thread</a>. It turns out you can also resize windows with Alt-(middle mouse button). Well, this is much easier. There is also a link to a <a href="https://bugs.launchpad.net/ubuntu/+source/metacity/+bug/160311">bug report</a> where they say this will be addressed in the coming 11.04 release. It seems like there will be 3 pixel wide invisible area around the window edges where you can grab and resize.<br />
<br />
Some other useful shortcuts:<br />
<ul><li>Alt-F7 - move active window (very convenient to get back a window from a second display/TV which is currently turned off)</li>
<li>Alt-(left mouse button) - move window</li>
</ul>Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-75404149789065046172011-03-25T00:47:00.000+02:002011-03-25T00:47:29.881+02:00Log in SlingThe default Sling user is <i>anonymous</i> and it has read-only access to the repository. So if this user attempts to change anything in the repository he gets an error like this<br />
<br />
<samp>javax.jcr.AccessDeniedException: <path>: not allowed to add or modify item</samp><br />
<br />
So in order to change the data they have to login with a user that has proper permissions. But we still want to allow anonymous visitors to read the content of our site (like search engines). We ask them to log in only if they choose to edit the content. One way to do this in Sling is like this:<br />
<br />
<samp><% </samp><br />
<samp>if (!currentSession.hasPermission(currentNode.path, "set_property"))<br />
response.sendRedirect(request.requestURL + "?sling:authRequestLogin=BASIC");</samp><br />
<samp>%> </samp><br />
<br />
Put this code at the beginning of an ESP page that performs content changes.Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-44345942662205094602011-02-09T01:03:00.002+02:002011-03-02T01:53:56.143+02:00Posting non-ASCII characters in web formsI just hit this issue. You write some non-ASCII text (e.g. in Cyrillic) in a form and when submitted the text appears garbled on the server side.<br />
<br />
It turns out this is a well known glitch in web development especially when done in Java. The main reasons for the mess are<br />
<ol><li>Web browsers do not specify the encoding of posted data</li>
<li>Java Servlet specification says that default request encoding should be ISO-8859-1 in contrast to UTF-8 which is universally used nowadays</li>
</ol>You can find a good description of this issue here <a href="http://www.crazysquirrel.com/computing/general/form-encoding.jspx">HTTP Form Character Sets and Related Problems</a>.<br />
<br />
<a href="http://wiki.apache.org/tomcat/FAQ/CharacterEncoding">Tomcat FAQ</a> recommends creating a filter to set the request encoding.<br />
<br />
But when using Wicket there is no such issue as they fix the request encoding to UTF-8 as described in <a href="https://cwiki.apache.org/WICKET/how-to-change-the-character-encoding.html">How to change the character encoding</a>.<br />
<br />
Unfortunately Sling guys did it in another way (<a href="https://issues.apache.org/jira/browse/SLING-508">SLING-508</a>) which requires me to put a hidden input named _charset_ with the value UTF-8 in all my forms. So they have adopted the ugly IE hack. :(<br />
This is also described in Sling <a href="http://sling.apache.org/site/request-parameters.html#RequestParameters-CharacterEncoding">documentation</a>.<br />
<br />
I wish Sling had a way to set this to UTF-8 in one place and get rid of it.<br />
<br />
Sometimes web development is so frustrating.<br />
<br />
<b>Update: Mar 2nd</b><br />
After picking up this discussion on Sling mailing list the guys there decided after all to make this configurable, see <a href="https://issues.apache.org/jira/browse/SLING-1998">SLING-1998</a>.<br />
Great! My forms now work without the _charset_ hack.Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com1tag:blogger.com,1999:blog-831919787210015364.post-24605482300643161352010-11-29T22:53:00.000+02:002010-11-29T22:53:46.709+02:00Sling gotchaA content-driven application normally implements the basic <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> operations. Using <a href="http://sling.apache.org/">Sling</a> this should be done relatively easy.<br />
As part of the Read operation you normally have to implement some listing of available resources. Being familiar with <a href="http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/index.html">JCR API</a> it would be natural to do it with this JavaScript code in your ESP page<br />
<code><br />
var iter = currentNode.<a href="http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Node.html#getNodes%28java.lang.String[]%29">getNodes()</a>;<br />
while (iter.hasNext()) {<br />
var childNode = iter.nextNode();<br />
...<br />
</code><br />
<br />
Yes, but no! The result is a big fat exception<br />
<code><br />
org.mozilla.javascript.EcmaError: TypeError: hasNext is not a function, it is org.mozilla.javascript.Undefined. (/apps/catalog/html.esp#11)<br />
</code><br />
<br />
Hm! currentNode is a JCR <a href="http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/javax/jcr/Node.html">Node</a> so getNodes() should return a javax.jcr.NodeIterator which is a java.util.Iterator. So the code looks correct but somehow <code>iter</code> here is not a Java object at all.<br />
<br />
I struggled with this several hours. I was very puzzled to see similar code in espblog sample working just fine. The only difference is that espblog uses QueryResult.getNodes() which still returns NodeIterator.<br />
<br />
Finally I found the answer in this <a href="http://www.mail-archive.com/dev@sling.apache.org/msg07296.html">thread</a>. It turns out Sling wraps Node.getNodes() to return a JavaScript object which has one property for each child node. Probably the idea was to easily iterate over that object with a for-each loop<br />
<code><br />
for each (var childNode in currentNode.getNodes()) {<br />
...<br />
</code><br />
<br />
Another solution is to use the property name instead of the getter method<br />
<br />
<code>var iter = currentNode.<b>nodes</b>;<br />
while (iter.hasNext()) {<br />
var childNode = iter.nextNode();<br />
...<br />
</code><br />
<br />
This seems to circumvent the wrapping done by Sling.<br />
<br />
This example illustrates a cute feature of <a href="https://developer.mozilla.org/en/Rhino_documentation">Rhino</a> which allows easy access of JavaBeans properties. <br />
<br />
Yes, server side JavaScript can be fun.Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com1tag:blogger.com,1999:blog-831919787210015364.post-46541961675300017102010-11-01T02:09:00.000+02:002010-11-01T02:09:47.159+02:00Dynamic Class Loading in OSGiSometimes you need to load an arbitrary class which you don't know in advance. In a normal Java application you would do that with Class.forName(String className). But in OSGi this will work only if your bundle imports explicitly the package of the class that you wish to load. In OSGi each bundle has its own class loader. OSGi services will not help if the class you wish to load is not exposed as a service, which is more likely the case.<br />
It would be great if at run-time you could find the bundle exporting the package of the desired class and ask that bundle to load the class using its own class loader.<br />
It turns out this is possible via <a href="http://www.osgi.org/javadoc/r4v42/org/osgi/service/packageadmin/PackageAdmin.html">PackageAdmin</a> service.<br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">org.osgi.service.packageadmin.PackageAdmin packageAdmin;</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">...</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">Class clazz = packageAdmin.<a href="http://www.osgi.org/javadoc/r4v42/org/osgi/service/packageadmin/PackageAdmin.html#getExportedPackage(java.lang.String)">getExportedPackage</a>(packageName)</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> .<a href="http://www.osgi.org/javadoc/r4v42/org/osgi/service/packageadmin/ExportedPackage.html#getExportingBundle()">getExportingBundle</a>().<a href="http://www.osgi.org/javadoc/r4v42/org/osgi/framework/Bundle.html#loadClass(java.lang.String)">loadClass</a>(className);</span><br />
<br />
Here packageName is the package name and className is the full class name.<br />
This way you can load any class from any package exported by any active bundle and still your bundle is independent from the bundle providing the class. This could be very useful when implementing some generic functionality like object persistence.Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com1tag:blogger.com,1999:blog-831919787210015364.post-81851636040948475532010-09-01T20:27:00.052+03:002010-09-01T20:27:00.277+03:00Ant & XercesHave you seen errors like this when parsing XML from Ant tasks?<br />
<br />
<pre>org.xml.sax.SAXParseException: Invalid encoding name "Cp1252".
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:208)
...
</pre><br />
The problem is in the encoding specified in the xml header<br />
<pre><?xml version="1.0" encoding="Cp1252"?></pre>This often appears in xml files generated by Java programs.<br />
<br />
Bug <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4665105">4665105</a> is filed for this issue but it is closed as "Not a defect".<br />
<br />
It turns out that the same XML file is parsed fine by the JRE libraries, but ant uses its own xml libraries - xml-apis.jar and xercesImpl.jar found under ant/lib. If I delete these two files, xml parsing in ant works fine.<br />
Luckily this issue seems solved in latest Ant 1.8.1. From the release notes:<br />
<pre>* Ant no longer ships with Apache Xerces-J or the XML APIs but relies
on the Java runtime to provide a parser and matching API versions.</pre><br />
A workaround.<br />
When parsing the xml file instead of<br />
<pre>DocumentBuilder.parse(file)</pre>use<br />
<pre>DocumentBuilder.parse(new InputSource(new FileReader(file)))</pre>This tells the parser to ignore the encoding specified in the xml header.Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-22045864290168368592010-08-27T00:18:00.000+03:002010-08-27T00:18:01.224+03:00Backup on LinuxOne of the few things for I still have to switch to Windows is <a href="http://dotev.blogspot.com/2009/12/backup.html">backup</a>.<br />
As I wrote before, for that job I have put up a small bat file that relies on <i>robocopy</i> to do the job.<br />
Finally I came up with a similar shell script for Linux that does the same job using <i>rsync</i>.<br />
Now the backup script on Linux reads the same list file as the backup script on Windows (my NTFS drives are mounted in Linux).<br />
It looks like this<br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">#!/bin/sh</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"><br />
</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">TARGET=/media/SAMSUNG/BACKUP</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">SYNC='rsync -rptgovF --delete --delete-excluded'</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"><br />
</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"># Backup Windows drives</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">LIST=/home/peter/Documents/Documents/Backup/backup.lst</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">cat $LIST | fromdos | sed s/\\\\/\\//g | while read -r line </span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">do</span></span><br />
<span class="Apple-tab-span" style="white-space: pre;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">echo BACKUP $line</span></span><br />
<span class="Apple-tab-span" style="white-space: pre;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">case "$line" in</span></span><br />
<span class="Apple-tab-span" style="white-space: pre;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">C:*) $SYNC "/media/Windows 7${line#C:}/" "$TARGET${line#C:}";;</span></span><br />
<span class="Apple-tab-span" style="white-space: pre;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">D:*) $SYNC "/media/Data${line#D:}/" "$TARGET${line#D:}";;</span></span><br />
<span class="Apple-tab-span" style="white-space: pre;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">esac</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">done</span></span><span class="Apple-tab-span" style="white-space: pre;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"> </span></span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"><br />
</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"># Backup Linux drive</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">echo BACKUP /home/peter</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;">$SYNC /home/peter/ "$TARGET/home/peter"</span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="font-size: small;"><br />
</span></span><br />
<span class="Apple-style-span" style="font-size: small;"><span class="Apple-style-span" style="font-family: inherit;">The F option tells rsync to look for file .rsync-filter in each directory. If it is present it specifies files to exclude from that directory.</span></span><br />
In a typical UNIX way several commands are chained via pipes.<br />
<i>fromdos</i> is used to convert the text file from Windows to UNIX format, i.e. strip CR chars as they would cause problems later on.<br />
<i>sed</i> is used to replace all back slashes to forward slashes.<br />
<i>${line#C:}</i> and <i>{line#D:}</i> macros produce the path without the drive.<br />
<br />
UNIX shell scripting proved once again to be very powerful.Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com0tag:blogger.com,1999:blog-831919787210015364.post-55208021055166844222010-08-23T20:15:00.046+03:002010-08-23T20:15:00.276+03:00Sling<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6k491DavuFyqBYRi-JVfhfL3vQLqlC2vyDmEUeqofLqJBR32Z8k9cNieVKX7X7nrJLjjO2WCBcK-f6jfAHjO4cdwzsKEeriIN6Acr9xpWS4JYJG011tZgPh3EnwfuVOhyphenhyphenZbc0xH3Cgg2x/s1600/sling_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6k491DavuFyqBYRi-JVfhfL3vQLqlC2vyDmEUeqofLqJBR32Z8k9cNieVKX7X7nrJLjjO2WCBcK-f6jfAHjO4cdwzsKEeriIN6Acr9xpWS4JYJG011tZgPh3EnwfuVOhyphenhyphenZbc0xH3Cgg2x/s320/sling_logo.png" /></a></div>Have been checking <a href="http://sling.apache.org/">Sling </a>recently. Basically yet another Java web framework, but this one has a rather interesting approach - it is content oriented. It is based on OSGi, JCR, REST, server side scripting, etc. The recently popular principle <i>convention over configuration</i> is heavily used.<br />
Found this brief <a href="http://www.eu.apachecon.com/presentation/materials/0000/0197/jcr-sling-bdelacretaz-aceu09.pdf">intro</a> to Sling.<br />
Also this <a href="http://dev.day.com/content/ddc/blog/2008/07/cheatsheet.html">cheat sheet</a> gives a condensed overview over the Sling way.<br />
<br />
Although both projects Sling and Jackrabbit are hosted at Apache, they are led by a company called <a href="http://www.day.com/">Day</a>.<br />
It is interesting that <a href="http://en.wikipedia.org/wiki/Roy_Fielding">Roy T Fielding</a> is a chief scientists at Day.Petar Dochevhttp://www.blogger.com/profile/12878691100856841782noreply@blogger.com1