24 Mayıs 2011 Salı

Takip Ettiğiniz Kişi Facebook Chat'te Çevrimiçi Olunca Haber Veren Program

O kadar lazım çok olur mu bilmem ama bana lazım oldu ve çözümü şöyle buldum. Daha farklı da yapılabilir tabi.

Ön Bilgi: Facebook Chat servisi XMPP/Jabber protokolü üzerinde çalışıyor. Bu protokolün belirtimlerine(specification) göre, ne zaman bir arkadaşınız FB Chat'te durumunu değiştirirse (Çevrimiçi, Dışarıda, Çevrimdışı) protokol istemcilerini bilgilendirir. MSN gibi yani.

Benim yöntemim bu protokolü kullanarak FB'a bağlanıp gelen uyarılar içinden istediğiniz kişiyi süzmekten oluşuyor.

Bunun için öncelikle bir FB Chat istemcisine ihtiyacımız var. Açık Kaynak Yazılım felsefesi sağolsun burada imdadımıza yetişiyor. SourceForge'da JFBChat adında işimizi görecek küçük bir program var. Kaynak kodlarını SVN'den indirebilirsiniz.



İşin zor kısmı programın FB'den gelen uyarıları dinleyen kısmı bulmakta. Kodu biraz deştiğinizde jfbchat.listeners.MyRosterListener sınıfının bu işi yaptığını fark edebilirsiniz. Gerisi artık sadece bir if kontrolüne kalıyor. Aşağıdaki ilk satır bir kullanıcı durumunu değiştirdiğinde konsola bir debug mesajı basıyor.

new DMessage(contact.getUser() + " has changed status and he is now " + contact.getPresence().toString() + ".").println();

contact.getUser()

Çağrısı ile kullanıcının FB'taki tam adına erişebilirsiniz.
Debug mesajından sonra şöyle basit bir if ile istediğiniz kullanıcıyı süzebilir, çevrimiçi olduğunda, sınırları hayalleriniz ve programcılık yeteneklerinizle belirlenmek üzere istediğiniz uyarıyı verdirebilirsiniz.

if (contact.getUser().indexOf("KULLANICI-ADI")!=-1)
{
System.out.println("Kahvenin Hatırı'nın debug çağrısı");
new MP3("C:\\PolisFilmTheme.mp3").play();
}

Netbeans projesi de burada.
Kolay gelsin.

22 Mayıs 2011 Pazar

Apache Commons IO Kütüphanesi

Apache Yazılım Derneği'nin Java'da sık karşılaşılan, JDK tarafından sağlanan sınıflarla yaparsanız "bin dereden su getirmeye" benzeyen görevleri, daha kolay biçimde gerçekleştirmenizi sağlayan araçları bir araya getirdiği Commons adında bir projesi var.

Bu yazıda bu projenin giriş çıkış işlemleri üzerine yoğunlaşan IO kütüphanesini inceliyoruz.Kütüphaneyi buradan indirebilirsiniz. commons-io-2.0.1.jar dosyasını projenizin classpath'ına eklemeniz yeterli.

Bu jar'ın içindeki bazı önemli sınıfları inceleyelim.

IOUtils sınıfı okuma, yazma ve kopyalama işlemleri için bazı yardımcı metodlar barındırır. Bu metodlar InputStream, OutputStream, Reader ve Writer nesneleri üzerinde çalışır.

Örneğin çok sık karşılaşılan bir işlem olan "herhangi bir InputStream'dan gelen verilere String formatında erişme" yi JDK sınıflarıyla şu şekilde gerçeklersiniz:

InputStream in = new URL( "URL-HERE" ).openStream();
 try {
   InputStreamReader inR = new InputStreamReader( in );
   BufferedReader buf = new BufferedReader( inR );
   String line;
   while ( ( line = buf.readLine() ) != null ) {
     System.out.println( line );
   }
 } finally {
   in.close();
 }

Ancak IOUtils sınıfını kullanarak, bu işlemi çok daha basit bir şekilde halledebilirsiniz:

InputStream in = new URL( "URL-HERE" ).openStream();
 try {
   System.out.println( IOUtils.toString( in ) );
 } finally {
   IOUtils.closeQuietly(in);
 }


Buradaki
IOUtils.toString( in );

metodu herhangi bir InputStream'i String olarak döner. Biz burada URL'den gelen bir akış(stream) kullandık. Ama sadece bununla sınırlı değilsiniz. InputStream dönen herhangi bir kaynak kullanabilirsiniz. Örneğin; File nesneleri, BufferedReader'lar...

FileUtils sınıfı File nesneleriyle birlikte kullanabileceğiniz çeşitli metodlar içerir. Bu metodları kullanarak dosyalarla okuma, yazma, kopyalama ve karşılaştırma işlemlerini çok daha kolay yapabilirsiniz. Örneğin; bir dosyayı satır satır okumak için şu kod parçasını kullanabilirsiniz.

File file = new File("/commons/io/project.properties");
List lines = FileUtils.readLines(file, "UTF-8");

FilenameUtils sınıfı da File nesneleri kullanma zorunluluğunu ortadan kaldırarak, dosya adlarıyla uğraşmanın daha basit yollarını sunar. Bu sınıf genelde Linux/Windows sistemler arası uyumluluğu sağlamak için kullanılır. Örneğin bir dosya adındaki çift noktaları kaldırmak için şu kodu kullanabilirsiniz.

String filename = "C:/commons/io/../lang/project.xml";
String normalized = FilenameUtils.normalize(filename);
// çıktı: "C:/commons/lang/project.xml"

FileSystemUtils sınıfı işletim sistemindeki dosya sistemi yapısı ilgili işlemler yapmak için JDK'da bulunmayan bazı yardımcı metodlar içerir. Örneğin: C diskindeki boş alan miktarını öğrenmek için;

long freeSpace = FileSystemUtils.freeSpace("C:/");

LineIterator sınıfıyla metin tabanlı bir dosyanın satırlarına kolayca tek tek ulaşabilirsiniz. LineIterator kurucu ile oluşturulabileceği gibi IOUtils ve FileUtils sınıfları üzerinden fabrika meodlarıyla da oluşturulabilir. Örnek kullanımı:

LineIterator it = FileUtils.lineIterator(file, "UTF-8");
 try {
   while (it.hasNext()) {
     String line = it.nextLine();
     /// do something with line
   }
 } finally {
   LineIterator.closeQuietly(iterator);
 }

Hazır Dosya Filtreleri
org.apache.commons.io.filefilter paketinde JDK'nın java.io.FileFilter ve java.io.FilenameFilter. interface'lerini birleştirip, bunlara daha gelişmiş ek özellikler katan IOFileFilter interface'i bulunur. Pakette ayrıca bu interface'in hazır örnekleri de mevcuttur. Bu filtreleri örneğin bir FileDialog nesnesinde sadece belli tür dosyaları göstermek için kullanabilirsiniz. Hazır filtrelerden bazıları şunlardır. Not: Sınıf isimleri yeterince açıklayıcı olduğu için, ayrıca açıklamalarını yazmadım.


DirectoryFilter, PrefixFileFilter, SuffixFileFilter, NameFileFilter, WildcardFileFilter, AgeFileFilter, SizeFileFilter, TrueFileFilter, FalseFileFilter, NotFileFilter, AndFileFilter, OrFileFilter

Örneğin, geçerli dizindeki, dizin olmayan, "A" ile başlayıp,  ".java" veya ".class" ile biten dosyaları listelemek için:

File dir = new File(".");
  String[] files = dir.list( 
    new AndFileFilter(
      new AndFileFilter(
        new PrefixFileFilter("A"),
        new OrFileFilter(
          new SuffixFileFilter(".class"),
          new SuffixFileFilter(".java")
        )
      ),
      new NotFileFilter(
        new DirectoryFileFilter()
      )
    )
  );
  for ( int i=0; i<files.length; i++ ) {
    System.out.println(files[i]);
  }


Bu pakette ayrıca FileFilterUtils sınıfı da mevcuttur. Bu sınıf az önce saydığın filtre sınıflarını import etmeden statik alanlar üzerinden çok daha kolay çağırmayı sağlar. Az önceki örnek bu sınıf yardımıyla tekrar yazılırsa şu hale dönüşür:

File dir = new File(".");
  String[] files = dir.list( 
    FileFilterUtils.andFileFilter(
      FileFilterUtils.andFileFilter(
        FileFilterUtils.prefixFileFilter("A"),
        FileFilterUtils.orFileFilter(
          FileFilterUtils.suffixFileFilter(".class"),
          FileFilterUtils.suffixFileFilter(".java")
        )
      ),
      FileFilterUtils.notFileFilter(
        FileFilterUtils.directoryFileFilter()
      )
    )
  );
  for ( int i=0; i<files.length; i++ ) {
    System.out.println(files[i]);
  }

Dosya Karşılaştırıcıları
org.apache.commons.io.comparator paketi java.io.File sınıfı için java.util.Comparator interface'inin birkaç hazır örneğini içerir. Bu karşılaştırıcılar dosya listelerini veya dizilerini sıralamak için kullanılabilir.

Bütün karşılaştırıcılar kendi özelliklerine göre uygun sort(File...) ve sort(List) metodlarını içerir. Örneğin, bir dizindeki dosyaları dosya adına göre sıralamak için;

File[] files = dir.listFiles();
NameFileComparator.NAME_COMPARATOR.sort(files);

Aynı işlemi tek satırda da yapabilirsiniz:

File[] files = NameFileComparator.NAME_COMPARATOR.sort(dir.listFiles());
  

CompositeFileComparator sınıfı karşılaştırma ve sıralama işlemini birkaç karşılaştırıcıyı birleştirerek yapabilir. Örneğin dosyaları önce türüne sonra da adına göre sıralamak için;

CompositeFileComparator comparator =new CompositeFileComparator(
DirectoryFileComparator.DIRECTORY_COMPARATOR,NameFileComparator.NAME_COMPARATOR);
File[] files = dir.listFiles();
comparator.sort(files); 


Akışlar(Stream)
org.apache.commons.io.input ve org.apache.commons.io.output paketleri akışların kullanışlı birkaç örneğini içerir. Bazıları;

  • Null output stream - Kendisine gönderilen bütün veriyi emer (yok eder).
  • Tee output stream - Çıktıyı tek akış yerine iki akışa yönlendirir.
  • Byte array output stream - JDK'daki abisinin daha hızlısı
  • Counting streams - Aldığı veriyi byte olarak sayan akış
  • Proxy streams - Proxy tasarım desenini uygular ve akışı uygun metoda yönlendirir.
  • Lockable writer
Bu yazıda Apache Commons'un IO kütüphanesini tanıtmaya çalıştım. Sınıflar ve kullanımları hakkında daha detaylı bilgiyi kütüphanenin Javadoc'unda bulabilirsiniz.

14 Mayıs 2011 Cumartesi

Basit Bir Anlık Mesajlaşma Yazılımı

Şimdi farkettim 2 sene olmuş İşletim Sistemleri dersinden ödev olarak basit bir MSN Messenger yapalı.

Proje hakkında bilgiyi aşağıdaki sunumda bulabilirsiniz:



İndirme bağlantısı da burada.

Pulp Fiction Duvar Kağıdı

Türkçesi: "İntikamımı aldığımda..."