Wednesday, February 27, 2008

QRCodes are becoming popular


QRCodes are two dimensional barcodes that can be decoded (scanned) at high speed. QrCode is created by Japanese corporation Denso-Wave. These two dimentisional bar codes are very common in Japan. They are widely used in ad sector.
URLs, Text, Phone numbers can be encoded in these codes. There are J2ME applications that can decode QRCodes. If you have a java enabled cell phone with a camera, install the application from http://reader.kaywa.com/ and begin scanning QRCodes.

I am going to list what can be done with a QRCode reader and a QRCode generator later in this blog.

The image in this post is an example of generated QR Code. Guess what is encoded in the picture. Install the QRCode reader and scan the image ;)

Sunday, February 3, 2008

RESTFUL URLs with Stripes

I came across with Stripes Framework 3 months ago. At first I said "yet another java mvc framework" but after reading its documentation I was suprised to see how easy a web application can be developed with Stripes.

I have developed several web applications with Struts and Spring MVC. The main difference between Stripes and other MVC frameworks is the configuration. Struts uses struts-config.xml to configure its action classes and its action forms. Stripes requires minimal configuration to get up and running (dispatcher conf. in web.xml), and zero configuration per ActionBean or page. If you have never heard of Stripes, go read Quick Start Guide, you will thank to me ;). I do not want to duplicate documentation in this post, because Stripes team has prepared a good and comprehensive documentation.

In this post I will explain how you can create clean urls with Stripes. Stripes does not need a configuration file to configure its action beans. If you does not supply any additional configuration Stripes configures your web application with the default RuntimeConfiguration class. An ActionResolver is responsible for finding your action beans and mapping HTTP requests to action bean methods. Stipes uses NameBasedActionResolver by default.
As it is explained here the default behaviour of NameBasedActionResolver is as follows:

  1. All classes that implements the ActionBean interface is searched. (By default Stripes searches for ActionBean implementations in classpath. But you can narrow the scope of this search by changing the default configuration. This will improve startup performance of your application. See ActionResolver Properties)
  2. Packages "web, www, stripes, action" and their parents are removed. For example "com.companyname.superproject.web.user.DetailsActionBean" becomes "user.DetailsActionBean".
  3. Action or ActionBean suffix is trimmed. "user.DetailsAactionBean" becomes "user.Details"
  4. "." is replaced with "/". "user.Details" becomes "/user/Details"
  5. Finally NameBasedActionResolver appends ".action" to the end of the action URL and we get "/user/Details.action"

If you want to use clear URLs like "http://www.mysite.com/user/details/12345" instead of "http://www.mysite.com/user/Details.action?userid=12345" you must write your custom ActionResolver implementation. Don't worry it is very easy. First in your web.xml tell Stripes to use your ActionResolver class:
web.xml

<filter>
<display-name>Stripes Filter</display-name>
<filter-name>StripesFilter</filter-name>
<filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
<init-param>
<param-name>ActionResolver.UrlFilters</param-name>
<param-value>/WEB-INF/classes</param-value>
</init-param>
<init-param>
<param-name>ActionResolver.Class</param-name>
<param-value>com.companyname.superproject.RestfulActionResolver</param-value>
</init-param>
</filter>

Then write a class that extends NameBasedActionResolver. You only need to override getBindingSuffix() and getUrlBinding(String s) methods. An implementaion (RestfulActionResolver.java) is listed below:
RestfulActionResolver.java

package com.companyname.superproject.RestfulActionResolver
import net.sourceforge.stripes.controller.NameBasedActionResolver;
import org.apache.log4j.Logger;

public class RestfulActionResolver extends NameBasedActionResolver {
@Override
protected String getBindingSuffix() {
return "";
}
@Override
protected String getUrlBinding(String s) {
String urlBinding = super.getUrlBinding(s);
return urlBinding.toLowerCase();
}
}

RestfulActionResolver finds ActionBean instances and performs HTTP requests bindings for you.
"com.companyname.superproject.web.user.DetailsActionBean" action bean is mapped to URL "/user/details".

I used Stripes version 1.4.3 in the above example.
I hope you enjoy the post.

Tuesday, January 29, 2008

Extended desktop configuration with xrandr

I've got Ubuntu 7.10(gutsy) running pretty well on my DELL Latitude D505 laptop. I'll try to explain how I configured extended desktop with a NEC 19'' LCD monitor.
We will use xrandr utility to configure multiple screens. Before using xrandr you must check xorg.conf file ( /etc/X11/xorg.conf )


Section "Screen"
Identifier "Default Screen"
Device "Intel Corporation 82852/855GM Integrated Graphics Device"
Monitor "Generic Monitor"
Defaultdepth 24
SubSection "Display"
Depth 24
Virtual 2304 1792
Modes "1280x1024@75" "1024x768@60"
EndSubSection
EndSection

The Virtual keyword is important. Sum of resolution widths and sum of resolution heights of two monitors are written in Virtual.
For example : 1280 + 1024 = 2304 and 1024 + 768 = 1792

You must restart X server after updating xorg.conf file. ctrl-alt-backspace is the shortcut to restart X. After successfully restarting X server, run the following commands:

xrandr --output VGA --mode 1280x1024
xrandr --output LVDS --mode 1024x768
xrandr --output VGA --right-of LVDS
First command sets VGA (19'' LCD monitor) resolution to 1280x1024. Second command sets laptop monitor resolution to 1024x768. The last command places the extended monitor (VGA) right of laptop monitor. That's it. At least it works for me.

For more information check intellinuxgraphics.org site.

Sunday, January 27, 2008

How to change GNOME desktop wallpaper programmatically

GNOME preferences are managed by the GConf tool. Each preference in the GConf repository is expressed as a key-value pair.
gconftool-2 -R /desktop/gnome
command displays all the preferences listed under "/desktop/gnome" repository. You can print the value of a key in the gnome preferences table with the "g" parameter.

ilkinulas@tututil:~/bin$ gconftool-2 -g /desktop/gnome/screen/default/0/resolution
1280x1024
The "R" option prints all subdirectories and entries under a directory, recursively.

ilkinulas@tututil:~$ gconftool-2 -R /desktop/gnome/background
color_shading_type = solid
secondary_color = #dadab0b08282
primary_color = #000000000000
picture_filename = /home/ilkinulas/Pictures/wallpaper/w1209.jpg
picture_options = scaled
picture_opacity = 100
draw_background = true
ilkinulas@tututil:~$ gconftool-2 -g /desktop/gnome/background/picture_filename
/home/ilkinulas/Pictures/wallpaper/w1209.jpg
You can set a key to a value with the option "s". When you set a gnome preference, applications that are interested in that preference will be notified. For example:

gconftool-2 -t str -s /desktop/gnome/background/picture_filename "/home/ilkinulas/Pictures/wallpaper/64269-1.png"
sets gnome desktop background picture to "/home/ilkinulas/Pictures/wallpaper/64269-1.png". The option "-t" is used to specify the type of the value of the key. If you execute the command above you will see that your desktop wallpaper is changed. Now lets write a shell script to randomly select a picture and set selected picture as wallpaper.

#!/bin/bash
DIR=/home/ilkinulas/Pictures/wallpaper
counter=0;
for i in `find $DIR -iname *.jpg -o -iname *.png -o -iname *.gif`
do
pictures[$counter]=$i;
counter=$counter+1;
done
index=$((RANDOM%${#pictures[*]}));
gconftool-2 -t str --set /desktop/gnome/background/picture_filename ${pictures[$index]};

If you do not want to execute the above script manually you can add a new crontab entry. I start working in the office at 8 am and I use "00 09 * * *" as my crontab schedule, I want my wallpaper change everyday at 9 am, if my computer is on ;)

If the way I explain in this post is too complicated you can try Webilder. Webilder delivers stunning wallpapers to your Linux desktop, directly from Flickr and Webshots. You choose what keywords (tags) to watch for, and photos are automatically downloaded to your computer. Webilder can also change the wallpaper every few minutes.

Saturday, January 26, 2008

ReadWriteLock example in Java

Writing multithreaded java applications is not a piece of cake. Extra care must be taken because bad synchronization can bring your application to its knees. The JVM heap is shared by all the threads. If multiple threads need to use the same objects or static class variables concurrently, thread access to shared data must be carefuly managed. Since version 1.5, utility classes commonly useful in concurrent programming is included in the JSDK.

In Java synchronized keyword is used to acquire a exclusive lock on an object. When a thread acquires a lock of an object either for reading or writing, other threads must wait until the lock on that object is released. Think of a scenerio that there are many reader threads that reads a shared data frequently and only one writer thread that updates shared data. It's not necessary to exclusively lock access to shared data while reading because multiple read operations can be done in parallel unless there is a write operation.

In this post i'll give an example usage of ReadWriteLock interface which is introduced in the Java 1.5 API Doc. In Java Api Documentation it says :

A ReadWriteLock maintains a pair of associated locks,
one for read-only operations and one for writing.
The read lock may be held simultaneously by multiple reader threads,
so long as there are no writers. The write lock is exclusive.

Reader threads can read shared data simultaneously. A read operation does not block other read operations. This is the case when you execute an SQL SELECT statement. But write operation is exclusive. This means all readers and other writers are blocked when a writer thread holds the lock for modifing shared data.


Writer.java This class represents a thread that updates shared data. Writer uses WriteLock of ReadWriteLock to exclusively lock access to dictionary.


01 package deneme.readwritelock;
02 
03 
04 public class Writer extends Thread{
05   private boolean runForestRun = true;
06   private Dictionary dictionary = null;
07   
08   public Writer(Dictionary d, String threadName) {
09     this.dictionary = d;
10     this.setName(threadName);
11   }
12   @Override
13   public void run() {
14     while (this.runForestRun) { 
15       String [] keys = dictionary.getKeys();
16       for (String key : keys) {
17         String newValue = getNewValueFromDatastore(key);
18         //updating dictionary with WRITE LOCK
19         dictionary.set(key, newValue);
20       }
21       
22       //update every seconds
23       try {
24         Thread.sleep(1000);
25       catch (InterruptedException e) {
26         e.printStackTrace();
27       }
28     }
29   }
30   public void stopWriter(){
31     this.runForestRun = false;
32     this.interrupt();
33   }
34   public String getNewValueFromDatastore(String key){
35     //This part is not implemented. Out of scope of this artile
36     return "newValue";
37   }
38 }



Reader.java This class represents a thread that reads share data.


01 package deneme.readwritelock;
02 
03 public class Reader extends Thread{
04   
05   private Dictionary dictionary = null;
06   public Reader(Dictionary d, String threadName) {
07     this.dictionary = d;
08     this.setName(threadName);
09   }
10   
11   private boolean runForestRun = true;
12   @Override
13   public void run() {
14     while (runForestRun) {
15       String [] keys = dictionary.getKeys();
16       for (String key : keys) {
17         //reading from dictionary with READ LOCK
18         String value = dictionary.get(key);
19         
20         //make what ever you want with the value.
21         System.out.println(key + " : " + value);
22       }
23       
24       //update every seconds
25       try {
26         Thread.sleep(1000);
27       catch (InterruptedException e) {
28         e.printStackTrace();
29       }
30     }
31   }
32   
33   public void stopReader(){
34     this.runForestRun = false;
35     this.interrupt();
36   }
37 }



Dictionary.java This is a simple and thread safe dictionary. Read operations are managed through ReadLock and write operations (updates) are managed throuh WriteLock.


01 package deneme.readwritelock;
02 
03 import java.util.HashMap;
04 import java.util.concurrent.locks.Lock;
05 import java.util.concurrent.locks.ReentrantReadWriteLock;
06 
07 public class Dictionary {
08   
09   private final ReentrantReadWriteLock readWriteLock = 
10     new ReentrantReadWriteLock();
11 
12   private final Lock read  = readWriteLock.readLock();
13   
14   private final Lock write = readWriteLock.writeLock();
15   
16   private HashMap<String, String> dictionary = new HashMap<String, String>();
17   
18   public void set(String key, String value) {
19     write.lock();
20     try {
21       dictionary.put(key, value);
22     finally {
23       write.unlock();
24     }
25   }
26   
27   public String get(String key) {
28     read.lock();
29     try{
30       return dictionary.get(key);
31     finally {
32       read.unlock();
33     }
34   }
35 
36   public String[] getKeys(){
37     read.lock();
38     try{
39       String keys[] new String[dictionary.size()];
40       return dictionary.keySet().toArray(keys);
41     finally {
42       read.unlock();
43     }
44   }
45   
46   public static void main(String[] args) {
47     Dictionary dictionary = new Dictionary();
48     dictionary.set("java",  "object oriented");
49     dictionary.set("linux""rulez");
50     Writer writer  = new Writer(dictionary, "Mr. Writer");
51     Reader reader1 = new Reader(dictionary ,"Mrs Reader 1");
52     Reader reader2 = new Reader(dictionary ,"Mrs Reader 2");
53     Reader reader3 = new Reader(dictionary ,"Mrs Reader 3");
54     Reader reader4 = new Reader(dictionary ,"Mrs Reader 4");
55     Reader reader5 = new Reader(dictionary ,"Mrs Reader 5");
56     writer.start();
57     reader1.start();
58     reader2.start();
59     reader3.start();
60     reader4.start();
61     reader5.start();
62   }
63   
64 }

Monday, January 21, 2008

Birkaç vi kısayolu

o : Bulunduğun satırın altına yeni bir satır açar ve yazmaya bu yeni satırdan devam edebilirsin.
w : İleriye doğru kelime kelime ilerler
b : Kelime kelime geriye gider.
cw : İmlecin üzerinde olduğu kelimeyi değiştirmeye yarar.
9G : İmleç 9. satıra gider.
H : İmleç sayfanın en tepesine gider (Birinci satıra değil görünen sayfanın ilk satırına)
L : İmleç sayfanın en altıne gider
~ : İmlecin üzerinde olduğu karakteri büyük harf ise küçük harfe, küçük harf ise büyük harfe çevirir. (case dememek için çektiğimiz sıkıntıya bak ya. Kısaca karakterin case'ini değiştirir)
. : son çalıştırılan komutu çalıştırılır.
c$ :İmlecin bulunduğu yerden satır sonuna kadar siler. Editor INSERT modunda kalır. Yazmaya devam edebiliriz.
mt : Imlecin bulunduğu satırı "t" etiketi ile işaretler 't ile imleç işaretli satıra uçar.

vi editörü ile ilgili daha detaylı türkçe bilgi için belgeler.org adresine bakabilirsiniz.

Friday, January 18, 2008

Başkaldıran dosya sistemlerini fuser ile hizaya getirin

Önce bu fuser da nedir diyenler için kısa bir açıklama:

Dosya sistemindeki bir dosyayı ya da bir soketi hangi
process'in kullandığını gösteren komut.

"Tamam da ne işime yarayacak dosyayı hangi process'in kullandığını öğrenmek" diyenler için de fuser kullanımı ile ilgili bir örnek verelim. Yeni yazdığınız bir CD'yi CD sürücünüze takıp mount ettiniz. CD içindeki dokumanlarla işiniz bittikten sonra CD'yi çıkartmaya çalıştığınızda aşağıdaki gibi bir mesajla karşılaşabilirsiniz:



Ya da komut satırında umount komutu ile CD'yi unmount etmek isteğinizde aşağıdaki gibi "device is busy" mesajı ile karşılaşabilirsiniz.



İşte fuser tam burada yardıma koşuyor. CD'yi meşgul eden process'in PID'sini bulmak için aşağıdaki işlemler yapılır.



Bizim örneğimizde aranan process 7614 numaralı evince dir.(Gnome Document Viewer) Bu process'i kapattıktan sonra CD yi problemsiz unmount edebiliriz.