31 Mart 2008 Pazartesi

Java Sms Api - Haber 2


Şimdilik Nokia S40 lar için çalışan ( s60 için deneyemedim :) ) SMS Api bitmis durumda. Gözden geçiriyorum. Eksiklikler, kodda hatalar var mı? Ben de sorunsuz çalışıyor.

Amacım projelerinize SMS özelliğini katabilmeniz. Gerçekten harika fikirler geliyor insanın aklına, çok güzel projeler geliyor. Cep telefonunu insanlar her zaman taşıyorlar, onlara her zaman ulaşmak mümkün oluyor. Telefonların bu güzelliğinden yararlanarak projeler geliştirmek gerekiyor artık.

Kısa bir süreliğine açık kaynak kodlu olmayacak, yani upload edeceğim jarlarda source codelar olmayacak :(

Ben pcsuite bluetoothla baglanıyorum, cablo ile de olması lazım diye
düsünüyorum deneme imkanım olmadığı için bir şey diyemeyeceğim. büyük
ihtimalle olur diye düşünüyorum, usb de bir nevi seri port,
baglandiginiz usb nin comport numarasını uygulamanıza girebilirseniz,
apiyi çalıştırırsınız diye umud ediyorum.


Gereken donanım ve yazılımlar,
-pc suite 6.82 or newer version
-bluetooth module or usb cable

az daha sabretmek lazım...

sabreden derviş :

http://afsungur.googlepages.com/SMSApi.rar



30 Mart 2008 Pazar

Java Thread Örneği - Yükleniyor Göstergesi

Java ile uygulama geliştirirken bir çok kez file'dan okuma veya database'e baglanma islemlerini gerceklestiririz. Ozellikle bazı zamanlarda saniyeler suren bir gecikme meydana gelebilir bu tip okumaları yaparken. Ve de bu isi threadsiz yapiyorsak, malesef kullanici dostu olamamisiz demek ki...

Örneğin, bir butonumuz var ve bu buton veritabanına bağlanıp bize bir Connection nesnesini handle edecek. Thread kullanmaz isek butona bastığımızda buton kullanıcının veritabanına baglanma islemlerini gerceklestirme icerisinde oldugundan tepki veremeyecek ve kullanıcı programın kilitlendiğini zannedecektir. Böyle bir durumu önlemek için thread kullanılabilir.

Threadler çalışan proseslerin birer parçasıdırlar. Ingilizce anlamı ipliktir. Islemci bir anda sadece bir instruction işleyebilir. Thread ile instruction işlendiği anda disk okuması yapılabilir veya ekrana görüntü basılabilir. Çünkü bu işlemleri direk yapan cpu değildir. Biz de threadin bu özelliğinden yararlanacağız.

2 clasımız var. birinden diğer threadli clasımızı çağıracağız. Thread kullanılmayan classta thread kullanılan clası şu şekilde çağıracağız bizim örneğimiz için:

ff_1 =new FeedbackFrame_1(this, conn, sp, smsControl, smsReader, smsSender);

ff_1 bir FeedbackFrame_1 clasına ait nesne ve bu clasın contructoru görüldüğü gibi bir çok obje alıyo. Bunları siz
uygulamanızın durumuna göre değiştirebilirsiniz. Peki FeedbackFrame_1.java dosyası nasıl bir dosya, içeriği ne:

import java.lang.reflect.*;
import java.awt.*;
import java.awt.event.*;
import java.sql.Connection;
import javax.swing.*;
import javax.comm.*;

/**
*
* @author Ahmet Fuat SUNGUR
* Sms kontrolunu saglamakla yukumludur. Soyleki serveri baslatmadan onceki ayarlarin bir thread
* aracigiyla yapilip, kullanici arayuzunu dondurmamak icin kullanilmis bir class'tir.
*/
public class FeedbackFrame_1 extends JFrame implements Runnable {

private SmsFlow sf;
private Thread t;
private JLabel label;
private int state;
private SerialPort sp;
private ComSettings comInstance;
private SmsControl sc;
private SmsReader sr;
private SmsSender ss;
private Connection conn;


public FeedbackFrame_1(SmsFlow sf,Connection conn, SerialPort sp,SmsControl sc, SmsReader sr, SmsSender ss) {
this.sf = sf;
this.sc = sc;
this.sr = sr;
this.ss = ss;
this.conn = conn;
this.sp = sp;
setupFrame();
t = new Thread(this);
t.start();
pack();
show();
}

private void setupFrame() {
label = new JLabel();
label.setPreferredSize(new Dimension(200,50));

Container c = getContentPane();
JButton stopButton = new JButton("Stop");
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
error();
}
});
c.add(label, BorderLayout.NORTH);
c.add(stopButton, BorderLayout.SOUTH);
this.setTitle("Baglantilar deneniyor...");
}

private void setText(final String s) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
label.setText(s);
}
});
} catch (InterruptedException ie) {
error();
} catch (InvocationTargetException ite) {
error();
}
}

private void error() {
t.interrupt();
if (SwingUtilities.isEventDispatchThread())
closeDown();
else SwingUtilities.invokeLater(new Runnable() {
public void run() {
closeDown();
}
});
}

private void closeDown() {
sf.setupCancelled();
hide();
dispose();
}
public SmsSender getSmsSender()
{
return this.ss;
}
public SmsReader getSmsReader()
{
return this.sr;
}
public SmsControl getSmsControl()
{
return this.sc;
}

public void run() {
// Simulate connecting to server

try{
/////
// Streamlari ayarliyoruz. DataOutput, DataInput, OUTPUT Stream...
setText("Stream aciliyorr...");
try
{
Thread.sleep(1000);
}
catch (InterruptedException ie) {}
sc.setStreams();


// Ve GSM modemimizle konusmaya basliyoruz.
// ilk mesaji gonderdik.
setText("İlk mesajlar gonderiliyor...");
try
{
Thread.sleep(1000);
}
catch (InterruptedException ie) {}
sc.send("AT");
sc.expect("OK");

setText("Karakter mod destegi...");
try
{
Thread.sleep(1000);
}
catch (InterruptedException ie) {}
// Mesajlarin pdu formatinda degil de text formatinda olmasini istiyoruz.
sc.send("AT+CMGF=1");
sc.expect("OK");

// Ve simdi sira geldi mesajlari okumaya ve gelen mesajlari parse edip
// gerekli cevabi kullaniciya gondermeye.
// Simdi GSM modemimizdeki mesajlari okurken 1 okuyup, okudugumuz
// mesaji irdeleyip, yorumlayip, gereken cevabi uretip, bu cevabi
// bize mesaj gonderen kullaniciya geri iletmemiz gerekiyor.
// Burada bir producer consumer problemi var. Producer Reader kismi,
// Consumer Sender kismi oluyor. Yani bir mesaj ilk once okunacak, bu mesaj
// ile ilgili islemler yapilmadan 2. mesaj okunmaya gecilmeyecek.
// Bunu asmak icin threadlarden yararlandik ve producer consumer
// problemini çözmek için SmsProducerConsumer clasini olusturduk.
// SmsReader ve SmsSender classlari constructorlarinda bu SmsProducerConsumer
// classina ait nesneyi alirlar ve bu sayede gerekli senkronizasyon
// saglanmis olur.
/*SmsFirstSettings sfs = new SmsFirstSettings(smsControl);
sfs.start();
smsControl = sfs.getSmsControl(); */
setText("SMSReader ve SMSSender Class'lari hazirlaniyor...");
try
{
Thread.sleep(1000);
}
catch (InterruptedException ie) {}
SmsProducerConsumer smsProducerConsumer = new SmsProducerConsumer();
sr = new SmsReader(sp,conn,sf,sc,smsProducerConsumer);
ss = new SmsSender(sp,conn,sf,sc,smsProducerConsumer);
if (Thread.currentThread().isInterrupted())
return;

SwingUtilities.invokeLater(new Runnable() {
public void run() {
sf.setupDone();
hide();
dispose();
}
});
}
catch(Exception e)
{}
}

public SerialPort getSerialPort()
{
return sp;
}
}


Burada önemli olan clasın Runnable interfacını implement etmesi, bunu unutmuyoruz.

ff_1 = new FeedbackFrame(...)
kodunu yazdığımızda yukarıdaki classın ilk run methodu çağırılıyor. Bu da bu husus açısından önemli...
Daha sonra yaptiğiniz baglantilari bir sekilde get etmeniz gerekiyor. o yüzden bu feedback clasına constructordan gonderdiginiz parametreleri get edebilecek metodlar eklemelisiniz...

iyi çalışmalar..

29 Mart 2008 Cumartesi

Jar Oluşturmak

aa klasöründeki Class dosyalarından jar oluşturmak için Komut satırından :

jar -cf yourjarfile.jar aa/

yazınız. Peki jar ne işe yarar :

- Classlarınızı jar haline getirip, yani tek dosya haline getirip, ileride api olarak bunu sunabilirsiniz.
- Classlarınıza tek dosya da ulaşmanızı sağlar.
- Mobil Cihazlara java dosyalarının aktarımını sağlar.



27 Mart 2008 Perşembe

FORALL Performance

FORALL
Örnek olarak bir tablodan çektiğimiz verilerle başka bir tabloyu doldurmamız gerekiyor. Yapacağımız iş nedir? Her select işlemi ile aldığımız veriyi insert ile tabloya eklemek veya bulk collect ile bir arraya veriyi atayıp daha sonra o array içerisinde FOR ile dönerek tabloya verileri ekleyebiliriz.
Bize bu konuda yardımcı olacak başka bir yapı var: FORALL. FORALL keywordu, Toplu DML Statementlerde performans artışı sağlayan çok önemli bir keyword. Somut bir örnekle FORALL’ın performansını gösterelim.
Step_1 : FORALL keywordlu procedure

create or replace procedure step_1 is
TYPE array_type_id IS TABLE OF TEST_1.ID%TYPE;
TYPE array_type_name IS TABLE OF TEST_1.NAME%TYPE;

iteration_time INTEGER := 1000;
varIdArr array_type_id := array_type_id();
varNameArr array_type_name := array_type_name();

BEGIN
SELECT ID,NAME BULK COLLECT INTO varIdArr,varNameArr FROM TEST_1;
FORALL i in varIdArr.first..varIdArr.last
INSERT INTO TEST_2 VALUES(varIdArr(i),varNameArr(i));
end;


Step_2: FOR keywordlu procedure

create or replace procedure step_2 is
TYPE array_type_id IS TABLE OF TEST_1.ID%TYPE;
TYPE array_type_name IS TABLE OF TEST_1.NAME%TYPE;

iteration_time INTEGER := 1000;
varIdArr array_type_id := array_type_id();
varNameArr array_type_name := array_type_name();

BEGIN
SELECT ID,NAME BULK COLLECT INTO varIdArr,varNameArr FROM TEST_1;
FOR i in varIdArr.first..varIdArr.last
LOOP
INSERT INTO TEST_2 VALUES(varIdArr(i),varNameArr(i));
END LOOP;
end;


Test Sonuçları:

SQL> exec runstats_pkg.rs_stop;

Run1 ran in 9 hsecs
Run2 ran in 125 hsecs
run 1 ran in 7,2% of the time

Name Run1 Run2 Diff
LATCH.dml lock allocation 1 0 -1
STAT...calls to get snapshot s 10 9 -1
LATCH.list of block allocation 0 1 1
STAT...IMU Flushes 1 0 -1
STAT...session cursor cache co 1 0 -1
LATCH.Consistent RBA 1 2 1
LATCH.lgwr LWN SCN 1 2 1
LATCH.mostly latch-free SCN 1 2 1
LATCH.OS process allocation 0 1 1
LATCH.enqueue hash chains 1 2 1
STAT...bytes received via SQL* 1,912 1,910 -2
STAT...messages sent 0 2 2
LATCH.library cache lock 2 4 2
LATCH.enqueues 0 2 2
STAT...enqueue requests 2 0 -2
LATCH.undo global data 24 28 4
STAT...consistent changes 14 19 5
LATCH.redo writing 3 8 5
STAT...cleanout - number of kt 22 28 6
STAT...active txn count during 22 28 6
STAT...calls to kcmgcs 22 28 6
STAT...consistent gets - exami 22 28 6
STAT...consistent gets 847 838 -9
STAT...consistent gets from ca 847 838 -9
LATCH.messages 2 14 12
LATCH.channel operations paren 0 14 14
LATCH.checkpoint queue latch 0 16 16
STAT...redo ordering marks 0 26 26
STAT...calls to kcmgas 0 26 26
STAT...workarea memory allocat -49 0 49
LATCH.SQL memory manager worka 6 73 67
STAT...change write time 3 78 75
STAT...free buffer requested 4 81 77
LATCH.cache buffers lru chain 4 81 77
STAT...recursive cpu usage 6 112 106
STAT...CPU used when call star 6 117 111
STAT...CPU used by this sessio 6 117 111
STAT...DB time 10 124 114
STAT...Elapsed Time 12 127 115
LATCH.object queue header oper 12 243 231
LATCH.simulator lru latch 56 877 821
LATCH.simulator hash latch 59 889 830
STAT...redo entries 87 10,036 9,949
LATCH.redo allocation 91 10,040 9,949
STAT...recursive calls 3 10,007 10,004
STAT...execute count 11 10,015 10,004
STAT...session logical reads 968 11,070 10,102
STAT...db block gets from cach 121 10,232 10,111
STAT...db block gets 121 10,232 10,111
STAT...db block changes 185 20,163 19,978
LATCH.library cache pin 60 20,068 20,008
LATCH.library cache 75 20,083 20,008
LATCH.cache buffers chains 2,238 52,343 50,105
STAT...undo change vector size 25,852 642,176 616,324
STAT...redo size 209,100 2,471,572 2,262,472

Run1 latches total versus runs -- difference and pct
Run1 Run2 Diff Pct
2,691 104,847 102,156 2.57%

PL/SQL procedure successfully completed

SQL>
Görüldüğü gibi FORALL’ı kullandığımız zaman 9hsec’te gerçekleşen iş, bu keywordu kullanmadığımız zaman 125hsec süre içersinde gerçekleşmiş. Ayrıca LATCH oranlarını karşılaştırdığımızda da 1/50 gibi bir oran karşımıza çıkıyor. Ve bu istatistikler bize FORALL’ın Toplu DML İşlemlerinde (INSERT,DELETE,UPDATE) ne kadar önemli bilgi sağladığını göstermiş oluyor.

BULK COLLECT Performance

BULK COLLECT
Bu denememizde BULK COLLECT adlı bir yapıyla tanışmış oluyoruz. Bu yapı bize sorgu sonuçlarını bir cursora değil de bir array’e aktarmamızı sağlıyor. Normalde bir tablodaki her satıra ait bir colonu yazdırmak istesek bunu şu şekilde yaparız:

FOR REC IN ( SELECT NAME FROM EMP)
LOOP
DBMS_OUTPUT….
END LOOP;


İşte, BULK COLLECT kullanarak bir cursor içerisinde değil de bir array içerisinde dönmüş oluyor. Ve bu PLSQL Kodunun performansını arttırıyor.
Denememizi şu şekilde yapacağız. 2 procedurumuz var. Step_1 BULK COLLECT ile veri çekiyor. Step_2 ise bildiğimiz şekilde.
Step_1 Proceduru :
create or replace procedure step_1 is
TYPE array_type_id IS TABLE OF TEST_1.ID%TYPE;
TYPE array_type_name IS TABLE OF TEST_1.NAME%TYPE;

varIdArr array_type_id;
varNameArr array_type_name;
BEGIN
SELECT id,name bulk collect into varIdArr,varNameArr from test_1 WHERE ID < 10000;

for i in varIdArr.first..varIdArr.last
Loop
dbms_output.put_line('>ID :' || varIdArr(i) || ' - NAME :' || varNameArr(i) );
end loop;
end;


Step_2 Proceduru:

create or replace procedure step_2 is
BEGIN
FOR REC IN ( SELECT * FROM TEST_1 WHERE ID < 10000)
LOOP
DBMS_OUTPUT.put_line('>ID :' || REC.ID || ' - NAME :' || REC.NAME);
END LOOP;
END;


Testimizi Başlatmak için:

exec runstats_pkg.rs_start;
exec step_1;
exec runstats_pkg.rs_middle;
exec step_2;
exec runstats_pkg.rs_stop;


Test Sonuçları :
SQL> exec runstats_pkg.rs_stop;

Run1 ran in 1048 hsecs
Run2 ran in 1139 hsecs
run 1 ran in 92,01% of the time

Name Run1 Run2 Diff
LATCH.mostly latch-free SCN 4 3 -1
STAT...session cursor cache co 1 0 -1
STAT...recursive cpu usage 3 4 1
LATCH.library cache lock 28 27 -1
LATCH.object queue header oper 4 5 1
LATCH.library cache lock alloc 1 0 -1
LATCH.undo global data 17 18 1
STAT...redo entries 11 12 1
LATCH.Shared B-Tree 0 1 1
LATCH.active checkpoint queue 4 3 -1
LATCH.kwqbsn:qsga 0 1 1
LATCH.cache buffers lru chain 0 1 1
LATCH.lgwr LWN SCN 4 3 -1
STAT...free buffer requested 0 1 1
LATCH.KMG MMAN ready and start 3 4 1
LATCH.enqueues 164 162 -2
LATCH.resmgr:resource group CP 2 0 -2
LATCH.library cache pin 26,809 26,811 2
LATCH.enqueue hash chains 166 164 -2
STAT...bytes received via SQL* 1,105,839 1,105,837 -2
STAT...db block changes 36 33 -3
LATCH.redo allocation 22 19 -3
LATCH.redo writing 15 12 -3
STAT...heap block compress 7 4 -3
LATCH.qmn task queue latch 0 4 4
LATCH.messages 72 68 -4
STAT...active txn count during 11 15 4
STAT...cleanout - number of kt 11 15 4
STAT...consistent gets - exami 11 15 4
STAT...calls to kcmgcs 11 15 4
LATCH.shared pool 50 55 5
STAT...consistent changes 25 20 -5
STAT...db block gets 37 44 7
STAT...db block gets from cach 37 44 7
LATCH.channel operations paren 56 48 -8
STAT...parse time cpu 14 1 -13
STAT...CPU used by this sessio 60 47 -13
STAT...CPU used when call star 63 47 -16
LATCH.checkpoint queue latch 72 54 -18
STAT...parse time elapsed 30 2 -28
STAT...DB time 87 56 -31
STAT...workarea memory allocat 31 -2 -33
LATCH.SQL memory manager worka 274 207 -67
STAT...undo change vector size 2,180 2,248 68
STAT...Elapsed Time 1,056 1,140 84
LATCH.shared pool simulator 107 15 -92
LATCH.simulator lru latch 54 232 178
LATCH.simulator hash latch 54 232 178
STAT...redo size 2,972 3,216 244
STAT...no work - consistent re 777 4,109 3,332
STAT...table scan blocks gotte 777 4,109 3,332
STAT...consistent gets 800 4,136 3,336
STAT...consistent gets from ca 800 4,136 3,336
STAT...recursive calls 6 3,344 3,338
STAT...session logical reads 837 4,180 3,343
LATCH.cache buffers chains 1,778 8,426 6,648
STAT...session uga memory 196,392 0 -196,392
STAT...session pga memory 458,752 0 -458,752
STAT...table scan rows gotten 497,103 2,246,371 1,749,268

Run1 latches total versus runs -- difference and pct
Run1 Run2 Diff Pct
80,153 86,968 6,815 92.16%

PL/SQL procedure successfully completed

SQL>


Bu Testte asıl dikkat etmemiz gereken birkaç nokta var. Bunlardan en önemlisi Tom Kyte’a göre Total Latches olayı. Görüldüğü gibi 2. Procedurumuzda bu daha fazla. Yani daha fazla gecikme meydana gelmiş. Diğer bakılabilecek önemli nokta ise elapsed time, yine aynı şekilde 1. Procedure 2.procedur’a göre daha performanslı elapsed time açısından.

Java SMS Api

Okuldaki projemde kullandığım SMS applicationu bir Api haline getirip,açık kaynak kodlu olarak geliştirilmesini sağlamak amacıyla yakında bir api çıkarmayı düşünüyorum. Bu api ile uygulama geliştiriciler kendi pclerine bağladıkları cep telefonundan Java kodlarıyla sms gönderip alabilecek. Bu şekilde projelerinize SMS özelliğini bu şekilde ekleyebileceksiniz.

Şimdilik Nokia S40 destekleyecek gibi, ama daha sonra tüm cihazlar için geliştirmeyi düşünüyorum.

Edit : Şu anda SMS Gönderme işlemi tamam, okuma işlemi var. Bu biraz uzun süreceğe benziyor. Ama beklemeye değer...

sabreden derviş :

http://afsungur.googlepages.com/SMSApi.rar

26 Mart 2008 Çarşamba

Fantastik Forvet Gitti

Kendini GittiGidiyor.com'da Fantastik Forvet başlığıyla açık artırmaya çıkaran amatör küme oyuncusu
Engin Kodan, 6.100 YTL'ye yeni kulübünü buldu.




GittiGidiyor, 'Bilkentli'nin Donu'ndan sonra en ilginç açık artırmalardan birine sahne oldu. İstanbul amatör küme takımlarından İmesspor'da oynayan Engin Kodan, bir 3. lig takımında oynamak için kendini GittiGidiyor.com'da açık artırmaya çıkardı.

Fantastik Forvet
başlıklı artırmaya ilgi büyüktü. 21.755 tekil kullanıcı tarafından
izlenen artırmaya 4 kulüpten teklif geldi. 5.000 YTL ile açılan
artırma, İstanbul bölgesinden bir kulübün 6.100 YTL bedelle Fantastik Forvet'i almasıyla son buldu.

20 Mart 2008 Perşembe

ScribeFire

ScribeFire, Firefox'a eklenebilecek çok kullanışlı olduğunu düşündüğüm bir add-on. Bu araç ile blogspot wordpress gibi bloglarınıza tek tıklama ile yazı ekleyebiliyorsunuz. Veya firefox'ta açtığınız herhangi bir sayfayı bloglayabiliyorsunuz...

Ve daha nicesi...

http://www.scribefire.com/getting-started/


17 Mart 2008 Pazartesi

18 Mart Çanakkele Zaferi

Canlarını, vatan uğruna gözünü kırpmadan verebilen şehitlerimizi ve vatanı için kolunu,bacağını,ayağını feda etmiş nice gazilerimizi saygıyla anıyoruz.

http://tr.wikipedia.org/wiki/%C3%87anakkale_Sava%C5%9Flar%C4%B1