12 Nisan 2008 Cumartesi

Java SMS Api v1.0

Hi everybody. At last, i've finished my SMS Api. May be it is not an API because it has only four classes that handle the SMSs.

After read the user guide carefully because installing and running this class some complicated. If you encounter any problem, sending an email that contains your problems, i want to help you to install and run this api.

May be there are some bugs, i have not checked them comprehensively. I will fix them later version.

Thank you,

Download this api :
http://afsungur.googlepages.com/SMSApi.rar

9 Nisan 2008 Çarşamba

XML Valid

Yazdığınız XML dosyalarınızı yine kendi yazdığınız DTD veya SCHEMA dosyalarıyla kontrol edebiliyorsunuz. XML Validator işleminin düzgün yapılıp yapılmadığını öğrenebileceğiniz kullanımı gayet kolay bir yazılım var:

Stylus Studio 2008 XML Enterprise Suite

indirmek için : www.stylusstudio.com/xml_download.html

Web üzerinden Schema Kontrolu ( biraz agir calissa da gereksinimleri karsilamakta ) :
http://tools.decisionsoft.com/schemaValidate/

6 Nisan 2008 Pazar

XML ve XSLT

XML, data change ve veri sakalamak için kullanabilecegimiz platform bagımsız oldukca elverisli bir teknoloji. Cok yaygın kullanımından dolayı bu yapıyı iyi anlamak gerekiyor. Çünkü yeri geldiğinde çok farklı cihazlar arasında veri alış-verişi yapılıyor ve bu veri alış-verişinin bir standart kullanılarak yapılması ilerde başka şahıslar tarafından bu işlemin geliştirilmesini sağlayabilir.

XML olmadığını düşünelim, Şöyle ki bir elektronik cihazdan bilgisayara veri okuyacaksınız. Elektronik cihaza bir kod embed ettiniz, bu kodda 5 tane arac bilgisi var diyelim ve bunları su sekilde cihaza kaydediyoruz:

Nesne1||Otobus||Plaka||34 OO 9899||Kapasite||200||Marka||Mercedes
Nesne2||Otobus||Plaka||34 aa 1121||Kapasite||400||Marka||Mercedes
Nesne3||Araba||Plaka||34 PP 3311||Kapasite||5||Marka||AUDI

Görüldüğü gibi bu kodda veya kod demeyelim, bu fileda araclara ait bilgiler var. Bilgiler karmasık bir düzende kaydedilmiş. Bunu okumak gercekten zor. Hadi biz bunu pcde kendi yazdıgımız bir prog.la okuduk diyelim bilgisayar tarafından, fakat başka birisi yine bunu okuyamayacak, aynı programın onda da olması gerekiyor. Bu yüzden bu işin bir standartlaştırmaya kavuşması gerekiyor. Belli kurallar dahilinde dataların saklanması gerekiyor ki bu işlem evrensel olsun, milyonlarca insan tarafından kullanılabilsin. O yüzden XML geliştirilmiş bu işin standartlaştırılması sağlanmıştır.

<?xml version="1.0"?>
<nesneler>
<nesne id="1">
<tip>Otobus</tip>
<plaka>34 00 9899</plaka>
<kapasite>200</kapasite>
<marka>Mercedes</marka>
</nesne>
<nesne id="2">
<tip>Otobus</tip>
<plaka>34 aa 1121</plaka>
<kapasite>400</kapasite>
<marka>Mercedes</marka>
</nesne>
<nesne id="3">
<tip>Araba</tip>
<plaka>34 PP 3311</plaka>
<kapasite>5</kapasite>
<marka>AUDI</marka>
</nesne>
</nesneler>


Yukarıdaki file'ı araclar.xml olarka kaydedip, çift tıkladığımızda ağaç yapısına benzer bir yapıyı göreceğiz. Çünkü şu ana kadar HTML'den yararlanmadık. Şimdi bu XML dosyasını HTML içinde XSLT ile görüntülemeye çalışalım.

İlk olarak XML File'ımızın 2.satırına yani <?xml version.. ile başlayan satırın bir altına şu satırı ekliyoruz :

<?xml-stylesheet type="text/xsl" href="araclar.xsl"?>

araclar.xsl dosyası araclar.xml dosyasıyla aynı klasörde bulunmakta ve araclar.xml dosyasının çift tıklanıp açıldığında anlamlı bir şekilde yani html gibi görüntülenmesini sağlayacak.

Peki araclar.xsl dosyasını nasıl oluşturuyoruz.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">

Yukarıdaki ifadelerden ilk ikisini tanıyoruz. 3. satırdaki ise XPath olayını belirtiyor. XPath ne? XPath aynı directory yapısı gibi çalışıyor. XML deki node'lara ulaşmamız için bir path tanımlıyoruz. Buradaki onu belirtiyor. Aşağıdaki satırlarda olayı daha iyi anlayacağız.


<html>
<body>
<h2> Vehicles </h2>
<table border="1">
<tr>
<th>Tip</th>
<th>Plaka</th>
<th>Kapasite</th>
<th>Marka</th>
</tr>

tablomuzu oluşturduk ve başlıklarını ekledik şimdi sıra geldi tablonun rowlarını doldurmaya :

<xsl:for-each select="nesneler/nesne">


directory'e ulaşır gibi xml de nodedan nodea atlıyoruz. nesneler nodundan nesne noduna atlıyoruz.

<xsl:sort select="kapasite" />


bilgilerin kapasite degerlerine gore sıralanmasını istedik. burada ascending sıralama gerceklesiyor. dilenirse order="" attribute ile bu deger degistirilebilir

<xsl:choose>

choose deyimi switch yapısına benziyor. when keywordleri switch yapısındaki case'lere, otherwise ise default kısmına denk düşüyor.

<xsl:when test="kapasite<100">
<tr>
<td bgcolor="red"><xsl:value-of select="tip" /></td>
<td><xsl:value-of select="plaka" /></td>
<td><xsl:value-of select="kapasite" /></td>
<td><xsl:value-of select="marka" /></td>
</tr>
</xsl:when>
<xsl:otherwise>
<tr>
<td bgcolor="yellow"><xsl:value-of select="tip" /></td>
<td><xsl:value-of select="plaka" /></td>
<td><xsl:value-of select="kapasite" /></td>
<td><xsl:value-of select="marka" /></td>
</tr>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

burada yaptığımız eğer xml deki dataların yani aracların kapasiteleri 100 den kucuk ise tiplerinin arka planı "red" olarak yani kırmızı olarak, 100 den buyukse tiplerinin arka planı sarı olacak sekilde tablolarımızı doldurmus oluyoruz.

KOMPLE KOD:

araclar.xsl

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2> Vehicles </h2>
<table border="1">
<tr>
<th>Tip</th>
<th>Plaka</th>
<th>Kapasite</th>
<th>Marka</th>
</tr>
<xsl:for-each select="nesneler/nesne">
<xsl:sort select="kapasite" />
<xsl:choose>
<xsl:when test="kapasite<100">
<tr>
<td bgcolor="red"><xsl:value-of select="tip" /></td>
<td><xsl:value-of select="plaka" /></td>
<td><xsl:value-of select="kapasite" /></td>
<td><xsl:value-of select="marka" /></td>
</tr>
</xsl:when>
<xsl:otherwise>
<tr>
<td bgcolor="yellow"><xsl:value-of select="tip" /></td>
<td><xsl:value-of select="plaka" /></td>
<td><xsl:value-of select="kapasite" /></td>
<td><xsl:value-of select="marka" /></td>
</tr>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>



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.