Saturday, November 1, 2003

XML Nasıl İşlenir

Bugünkü yazımızda, XML işlemcileri hakkında yazacağız. Önümüzde ana iki seçenek var.

* DOM
* SAX

DOM, SAX'tan daha yaşlıdır. XML dökümanlarını işlemek için ilk önce DOM kullanıyordu herkes. Fakat DOM'un bazı dezavantajları var. Mesela, XML dökümanı DOM ile işlenirse, DOM programı bütün XML kayıdı tamamen hafızaya alınır. Büyük XML kayıtları için bu işlem yavaş kalabilir.

Eğer bütün XML dosyasını nasıl olsa işlemek istiyorsanız, o zaman DOM işinize yarayabilir. Fakat XML dosyasından, sadece "birkaç" özel bölümlerden okuma yapmak istiyorsanız, SAX kullanmak daha hızlı olacaktır.

SAX, "vaka" modeli ile çalışır. Vaka modeli, yani Java dilinde 'event' modeli, normâl alışık olduğumuz, "sıralı işleyen" program modelinden biraz farklıdır. Sıralı işleyen programda, komutlar sıra ile işlenir. Programcı bu sırayı kod içinde belirtmiştir, önce şu olacak, sonra bu.

Vaka modeli içinde, şöyle demek mümkündür. "Ne zaman X olayı olursa, Y komutunu işlet".

Bu düşünce şeklinin, programlama stilinize etkileri büyüktür. Artık, sıralı dizi gibi işleyen komutlar yerine, artık vukuat komutları yazar hale geliyorsunuz.

SAX program modeli vaka üzerine kurulduğu için, cok hızlı bir şekilde XML işlemi mümkün olur. Çünkü artık işlemci, bütün dosyayı hafızada tutması gerekmez; böylece sadece istenen yere gelince, bir "vaka" başlatır. Sizin vaka komutlarınızda hemen o anda işleme konur. O komut içinde ne yapacağınız size kalmış. Veri tabanına yazabilirsiniz, e-posta gönderebilirsiniz, başka bir XML dosyasi içine kopyalayabilirisiniz.

SAX için yazılmış örnek bir program. Bu program title başlığında girilmiş bilgileri XML dökümanından buluyor.
    class VakaKomutu extends DefaultHandler{

protected String tag = null;
protected String content = null;

public VakaKomutu ()
{
super();
}

public String getContent()
{
return content;
}

public String processFile(String file) throws Exception
{
VakaKomutu komut = null;
try {
//System.out.println("processing .." + file);
XMLReader xr = XMLReaderFactory.createXMLReader( "org.apache.xerces.parsers.SAXParser");

komut = new VakaKomutu();
xr.setContentHandler(komut);
xr.setErrorHandler(komut);

FileReader r = new FileReader(file);
xr.parse(new InputSource(r));
} catch (Exception e) {e.printStackTrace(); throw e;}
//System.out.println("returning content... " + content);
if (komut == null )
return "title";
else
return komut.getContent();
}

public void startElement (String uri, String name,
String qName, Attributes atts)
{
if ("".equals (uri)){
//System.out.println("Start element: " + qName);
if ("title".equals(tag) == false) {
tag = qName;
//System.out.println("=====================");
//System.out.println("tag is " + tag);
//System.out.println("content is " + content);
}
}
else {
//System.out.println("Start element: {" + uri + "}" + name);
}
}

public void characters (char ch[], int start, int length)
{
if ("title".equals(tag) && content == null) {
content = new String(ch, start, length);
//System.out.println(content);
}
}

}

JDOM yardımı ile daha kolay XML işlemek

JDOM, Java için yaratılmış bir araç olarak, XML işlenmesini çok kolaylaştırıyor. JDOM tasarımı Java dilinin özelliklerinden faydalanabilecek gibi yapılmış. Ama acaba öteki standart arayüzlerin yerini alabilecek kadar etkili mi? Bu yazıda beraber göreceğiz.

Programcı olarak herhalde 80-20 kuralını duymuşsunuzdur (Pareto'nun kuralı diye de bilinir). 80-20 kuralı derki "Metod (tasarım) düzenleri önümüze çıkabilecek şartların 100'ünden 80'inine çözüm getirebilir. Geri kalan 20 durum için metodun dışına çıkıp, o şarta özel çözüm bulmak gerekir". Bu sözün programcılar için önemli dersi şudur: Herhangi bir teknolojiyi ele aldığımızda, bu teknolojinin önümüzdeki problemlerin yüzde seksenini muazzam rahatlıkta çözebilmemize yardım etmesi gerekir.

Ne yazık ki yazılım ürünleri ve standartları bazen bu şartlara göre gelişmiyor. Özellikle Java/XML teknolojilerine baktığımızda 80/20 kuralının birçok kere kırıldığı yerleri görüyoruz. Java dünyasında XML arayüzleri ve ürünleri enflasyonu vardır; Kimi ürün büyük bir şirket tarafından desteklenmiştir, kimisi tek bir XML işlemi etrafına özel yazılmıştır, kimisi de bütün çözüme gayet çetrefilli çözümler getirmeye uğraşmıştır. Fakat 10 koddan 8'ini çözecek, sürekli üst üste yaptığımız işlerde yardımcı olacak kütüphane nerede? Hani o XML ağaç yapısını basitçe işleyebileceğimiz, değiştirebileceğimiz Java diline uygun bir yazılımdan bahsediyoruz.

JDOM işte tam bu sorunlara çözüm olarak yazılmıştır.

Java ve XML

Birçok yönden Java, XML işlemek için en uygun dil haline geldi. Apache Vakfı ve IBM DeveloperWorks tarafından baslatılan büyük atılımlar sayesinde şu anda Java için XML işleyebilen, değiştirebilen esnek kod bazları mevcut.

Biraz da tarih. Java 2 standardı XML ünlü olmaya başlamadan önce piyasaya çıktığı için, Java 2 dahilinde XML yönünden birçok eksik var. Bu yüzden Sun, hem XML eklentileri yapabilmek hem de Sun dışında yaratılmış olan teknolojilere 'evet' diyebilmek için JSR sürecini kullanıyor. Bu sayede eklenen JAXP standardı akılda en çok kalan yenilerden biri. JAXP dahilinde 3 paket eklendi.


* org.w3c.dom: W3C standard arayüzlerinin Java'da gerçekleştirilmiş hali.
* org.xml.sax: olaya dayalı (event driven) XML işleyici basit arayüz
* java.xml.parsers

Bu paketlerin eklenmesi iyi bir şey olsa da, sonuçta yapılan 'zaten revaçta olan' standardlara evet demektir. Hala eksik olan Java'nın dil yapısına uygun esnek bir XML işleyici kütüphane idi.

Hoşgeldin JDOM. Ünlü iki Java yazarı olan Brett McLaughlin ve Jason Hunter tarafından yazılan JDOM, 2000 yılında serbest kod lisansı ile Apaçe projesine dahil edildi. Dünyanın her tarafındaki Java kullanıcılarında aldığı tavsiyeler/hata onarımları ile büyüyerek günümüze geldi. Amacı özetle, Java'ya uygun, basit ve esnek XML işleyici kütüphanesini oluşturmaktır.

JDOM Dosyalarını Yaratmak ve Kullanmak

JDOM alıştığımız Java kodlama tekniklerini kullanıyor. Lazım olan her yerde Java new kelimesi kullanmak mümkün; çetrefilli Factory (Fabrika) nesnelerine gitmemize gerek yok. Mesela, sıfırdan bir XML dosyası yaratmak için ne yapmamız gerektiğine bakalım.

<?xml version="1.0" encoding="UTF-8"?>
<araba no="123fhg5869705iop90">
<!--Araba tarifi-->
<marka>Toyota</make>
<model>Celica</model>
<sene>1997</year>
<rank>yesil</renk>
<plaka il="34">HC-176</plaka>
</araba>


Hemen önceden bir kök (üst) elemanı yaratalım.

Element arabaEleman = new Element("araba");
Document benimBelge = new Document(arabaEleman);


Bu basamak yeni bir org.jdom yaratmış oldu, ve bu elemanı org.jdom.Document benimBelge'nin üst düğümü haline getirdi. Her XML dosyasına mutlaka bir tane kök gerektiği için kurucu işleme Element nesnesini bildirgeç verildiğini görmüş olduk.

Şimdi no özelliğini ekleyeceğiz.

arabaEleman.addAttribute(new Attribute("no", "123fhg5869705iop90"));


Başka yeni elemanlar eklemek zaten basit. Marka elemanını ekleyelim:

Element marka = new Element("marka");
marka.addContent("Toyota");
arabaElemani.addContent(marka);


Not geçelim: Element nesnesinin işlemi addContent geriye Element döndürdüğü için, aslında aynı satırı şöyle de yazabilirdik:

arabaEleman.addContent(new Element("marka").addContent("Toyota"));


..dersek aynı işi görmüş oluyoruz. Bazıları 'ilk satır daha okunaklı' diyebilir, fakat aynı anda birden fazla Element yaratıyorsanız ikinci satır daha okunaklı olabilir. Devam edelim.

arabaEleman.addContent(new Element("model").addContent("Celica"));
arabaEleman.addContent(new Element("sene").addContent("1997"));
arabaEleman.addContent(new Element("renk").addContent("yesil"));
arabaEleman.addContent(new Element("plaka").addContent("HC-176").addAttribute("il", "34"));


Farkettiyseniz plaka elemanı dahilinde hem elemanın kendisini hem de 'il' dediğimiz bir özellikde ekledik. Bunun mümkün olmasının sebebi addContent işleminin gene aynı Element nesnesini geri döndürmesidir. Böylece zincirleme ekleme yapmak kolaylaşıyor. Bazi kütüphaneler (!) Element yerine void döndürüyorlar.. Cık cık cık.

Yorum ekleyelim:

arabaEleman.addContent(new Comment("Araba tarifi"));


Mavcut XML dosyasını işlemekte benzeri bir halde oluyor. Mesela sene elemanına bir göstergeç almak için Element nesnesi üzerindeki getChild işlemini kullanmamız lazım.

Element seneElemani = arabaEleman.getChild("sene");


Bu getChild çağrısı, ilk çocuk elemanı geri getirir. Eğer sene elemanı yok ise, o zaman null (sıfır) geriye gelir. Ayrıca dikkatinize sunmak istedim: Geri gelen değeri üst-dönüşümden (upcast) geçirmemiz gerekmedi (DOM'da öyle olacaktı). Element nesnesinin çocukları aynı şekilde Element. Ne kadar kolay değil mi? Devam edelim, sene elemanını belgeden çıkarmayı görelim.

boolean cikarildi = arabaEleman.removeChild("sene");


Son satır sadece sene elemanını çıkarır, belgenin gerisi aynı şekilde kalır.

Şimdiye kadar gördüğümüz XML dosyalarının yaratılması ve işlenmesi. Artık biten belgeyi sabit diske yazmanın zamanı geldi.

try {
XMLOutputter yazici = new XMLOutputter(" ", true);
yazici.output(benimBelge, System.out);
} catch (java.io.IOException istisna) {
istisna.printStackTrace();
}


XMLOutputter nesnesinin bazı formatlama seçenekleri var. Üstte gösterdiğimiz, her çocuk düğümün, bir üstündeki düğümden iki karakter sonra geleceği. Ayrıca, her elemandan sonra yeni bir satıra geçmek istiyoruz. XMLOutputter ya Writer nesnesine, ya da OutputStream nesnesine yazım yapabilir. Yani normal dosyaya yazmak için aşağıdakini yapmamız yeterli.

FileWriter yazan = new FileWriter("/bir/dizin/benimDosya.xml");
yazici.output(benimDosya, yazan);
yazan.close();


Öteki XML Arayüzleri ile Etkileşim

JDOM'un ilginç özelliklerinden biri de, öteki XML kütüphaneleri ile olan uyumu. JDOM ile Stream ve Reader nesneleri ile konuşabilmenin yanısıra, SAX EventStream ya da DOM Document nesneleri ile konuşabilmeniz mümkün. Böylelikle JDOM'u çok-arayüzlü ortamlarda kullanmanız mümkün oluyor. Ayrıca, daha sonraki örneklerde göreceğimiz üzere JDOM'un iç yapılarına başka kütüphanelerin erişmesi de mümkün.

JDOM'u kullanabileceğimiz başka bir yer, zaten mevcut olan XML dosyalarını işlemek. Bunu org.jdom.input paketini kullanarak yapacağız.

try {
SAXBuilder yapici = new SAXBuilder();
Document baskaBelge =
yapici.build(new File("/bir/dizin/ornek.xml"));
} catch(JDOMException i) {
i.printStackTrace();
} catch(NullPointerException i) {
i.printStackTrace();
}


İşte SAX'tan gelen bu belgeyi önceki yöntemleri kullanarak işleyebilirsiniz.

Ayrıca, diğer bir JDOM kullanımı gene Apaçe vakfından Xalan ile olabiliyor. Mesela ekteki dosyalara bakarak, bir İnternet araba satış mağazası için İnternet sayfaları yaratacağımızı düşünelim. Bu sayfalar araba detay bilgisi verecek. Bunu için JDOM Document nesnesi ile birlikte XSL kullanacağız ve servlet'in OutputStream'ine HTML basacağız.

Bize lazım olan araba.xsl adlı bir dosya.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/araba">
<html>
<head>
<baslik><xsl:value-of select="marka"/> <xsl:value-of select="marka"/>
</head>
<body>
<h1><xsl:value-of select="marka"/></h1><br />
<h2><xsl:value-of select="model"/></h2><br />
<table border="0">
<tr><td>no:</td><td><xsl:value-of select="@no"/></td></tr>
<tr><td>Sene:</td><td><xsl:value-of select="sene"/></td></tr>
<tr><td>Renk:</td><td><xsl:value-of select="renk"/></td></tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>



Şimdi org.jdom.Document nesnesini DOM Document nesnesine çevirelim, ve Xalan'a gönderelim. HTML'e nasıl çeviri yapılacağını anlatan XSL dosyası, ve farz edilen bir uygulama suncusundan gelen servlet OutputStream nesnesini de ekleyerek tabii ki.

TransformerFactory tFabrikasi = TransformerFactory.newInstance();

// XML ve XSLT belgeleri icin giris kaynaklarini yarat.
org.jdom.output.DOMOutputter yazici = new org.jdom.output.DOMOutputter();
org.w3c.dom.Document domBelgesi = yazici.output(benimBelge);
javax.xml.transform.Source xmlKaynagi =
new javax.xml.transform.dom.DOMSource(domBelgesi);
StreamSource xsltKaynagi =
new StreamSource(new FileInputStream("/bir/dizin/araba.xsl"));

// Cikis sonucunu HTTPResponse OutputStream kullanarak yarat.
StreamResult xmlSonucu = new StreamResult(response.getOutputStream());

// XSLT ceviricisi al
Transformer cevirici = tFabrikasi.newTransformer(xsltKaynagi);

// Ceviriyi yap
cevirici.transform(xmlKaynagi, xmlSonucu);


Bu örnekte çıkışı Java servlet'ten HTTPResponse OutputStream nesnelerine verdik. Fakat, bu çıkış geyet rahat bir şekilde normal dosya da olabilirdi. (XMLOutputter örneğinde gördüğümüz gibi). Kullandığımız DOMOutputter ile Xalan için XML kaynağı yarattık. Aynı kaynağı Document nesnesini XMLOutputter kullanarak String yapmak, ve onu StreamSource'a çevirerekte yapabilirdik. Esnekliğe bakın. JDOM çıkışı, String, SAX Event, Stream, hatta DOM Document dosyası bile olabilir. Böylece JDOM'un başka türden giriş bekleyen yazılımlar ile çalışabilmesi sağlanmıştır.

Birkaç satırda JDOM ile yapabileceğimiz birçok şey var. Bu yazıda gördüklerimiz XML'i yoktan yaratmak, olanı işleyebilmek, hatta XML üzerinden HTML sayfasına çevirmek oldu.

Sonuç olarak başlangıçtaki sorumuza gelelim. JDOM, şu anki mevcut arayüzlerden iyi mi? Eğer rüyalarızı bile Java dilinde gören birisi iseniz, cevap bizce 'Evet'.

Kaynaklar


* Bu yazının örnek kodları. JDOM, Xerces, ve Xalan'ı CLASSPATH'e eklemeyi unutmayın.
* JDOM projesi
* JDOM, Xerces, Xalan ve öteki XML ürünleri için Apaçe sitesini tavsiye ederiz.

Bu yazı ilk önce IBM developerWorks sitesinde yayınlanmıştır.

DOM ve XPATH kullarak XML işlemek

DOM belge işleme yöntemi, W3C kurumu tarafından kabul edilmiş dil, sonuç ortamından bağımsız bir belge işleme standartıdır. DOM, bir XML belgesini temsil edebilecek arayüzler tanımlar, ve bu arayüzler içindeki işlemler XML dosyalarındaki elemanlara erişim ve değiştirme gibi hizmetler sağlar. DOM oldukça yaygın destek görüyor ve birçok programlama dili üzerinde kodlanmış halde: Java, Perl, C, C++, Tcl ve Phyton.

Bu yazıda gösterecegimiz üzere DOM, akım temelli XML işlem yöntemleri yeterli olmadığı durumlarda (mesela SAX gibi) çok yararlı olacak. Akım temelli yöntemlerden kastımız, XML dosyasındaki elemanları teker teker işleyen, bütün belgeyi 'görmeyen' türden yöntemler. DOM bütün XML dosyasını hafızada ağaç veri yapısı kullanarak tutabilir.

Ne yazik ki, DOM tarifnâmesinin dilden-bağımsız bölümleri, ve XML belgesini soyutlayarak temsil etmek için öngördüğü 'herşey bir ağaç yapısında ki düğüm noktasıdır" gibi kavramları yanlış yapmayı daha rahat hale getiriyor, ve kullanan kodun yapısındaki aksaklıkları teşvik ediyor. Geçmişte DOM kullanan projelerimizin kodlarına baktığımızda bunu berrak olarak gördük. Bu genel problemleri çözümleri ile burada aktaracağız.

Belge Nesne Modeli (DOM)

DOM'a göre XML dosyasının her yeri bir düğüm noktasıdır, ve bu noktalar içindeki bilgiler 'çeşit' bilgisi ve 'değer' bilgisi olarak bilinir. Mesela ekteki XML parçasına bakalım.

<paragraf duzenle="sola">Bu<it>sola yatık</it>bölüm.</paragraf>


Yukaridaki XML dosya parçası, aşağıdaki görüntü ile temsil edilebilir.


Belge, Eleman, Metin ve Deger olarak tanımlanan parçalar DOM düğüm noktasıdır.

Fakat bu zarif tanım, bazı sorunları beraberinde getiriyor. Mesela ekteki XML parçasını düşünün. Deger . Sanırsınız ki, 'Deger' diye gösterilen metin, Java String nesnesi ile temsil edilecek, ve erişmek için, getDeger() gibi bir işlem yeterli olacak. Gerçekte, yukarıdaki metin bir Düğüm (Node) noktasıdır, ve başka bir dügüm noktası olan 'etiket-ismi' noktasının altında bulunur. (Çocuk düğüm olarak). Bunun yapılmasının DOM tasarımcıları tarafından mutlaka bazı sebebleri vardı: etiket-ismi altında bazen başka belge elemanları çocuk değerler olarak bulunabilirdi, bu gibi durumlarda metin değerini String olarak almak anlamsız olacaktı. Fakat, her şeyin dügüm noktası olarak görülmesi, sadece metin lazım olan (%80 ihtimalle) şartlar için programcılık hatalarını kolaylaştırmış oldu.

Tasarım Sorunları

DOM'ın dilden-bağımsız özelliğinin başka bir kötü yan etkisi de şudur: Her dilin kendine özgü benzer-oluşları mevcuttur, yani çok kez kullanılmış ve işlediği bilinen kullanım kalıpları. Ne yazık ki, DOM ortak bir dil için yazıldığı için, her dilin kendine hâs ve güçlü olan özellikleri DOM altında kullanılamıyor. Mesela, Element diye bilinen Eleman nesnesi bildiğimiz Java 'new' kelimesi ile yaratılamıyor, programcılar dış nesnelere (Factory diye bilinir yâni Fabrika) Element nesnesini yarattırmak zorunda kalıyorlar. Düğüm listeleri (çocuk düğümler örneğinde gördügümüz gibi) NodeList nesnesi içinde bulunuyor, fakat bütün Java programlarımızda java.util.List ve java.util.Iterator nesnelerini kullanmaya alışığız. Böyle ufak değişiklikler, toplana toplana karşımıza acaip kodlama yöntemleri ve kod fazlalığı olarak çıkıyor, ve programcıları 'DOM-nevi kodlamayı öğrenmeye; mecbur bırakıyor; hâlbuki Java-nevi kodlabilsek işimiz daha rahat olacak.

DOM tasarımına göre, herşey bir Dügümdür (Node). Bu yüzden neredeyse her XML değeri, meselâ Belge (Document), Eleman (Element) ve Değer (Attr) Düğüm denen Node arayüzünü uzatıyor. Tasarım olarak gayet muntazam olan bu yöntem sayesinde, her DOM gerçekleştirmesi kendi nesnelerini kendileri kodlayarak, ara nesnelerden geçmeden arayüzleri kullanıcıya açık bırakabiliyor.

'Herşey bir düğümdür' tasarımının problemi elimizde olan Düğüm çesitlerinin fazlalığı, ve bu dügüm noktalarına erişirken birörnek olmayan yöntemler. Mesela insertData yöntemi CharacterData düğümlerinin değerini vermek için kullanılıyor, fakat Attr düğümleri için setValue yöntemi kullanılıyor! Değişik düğümler için değişik arayüzler kullanınca nesnesel tasarımda önemli olan birbiçimlik kalmıyor, herşeyi Düğüm yaparak kazandığımız muntazamlığı kaybediyoruz. Çünkü programcıların öğrenim eğrisi yükseliyor.

JDOM

JDOM kütüphanesi, bahsettiğimiz problemlere çözüm olarak yazıldı. DOM'un dilden-bağımsız problemlerini çözerek DOM'a daha bir Java-nevi erişim şekli kazandırmaya çalıştı. Ve çok tekrar edilen kullanım yöntemleri için kestirme metodlar ve işlemler kazandırmaya uğraştı. JDOM'a göre her düğüm değişik bir nesnedir (Belge, Eleman ve Değer gibi), bu sayede programcılar 'new' kelimesini kullanıp Düğüm yaratabiliyorlar, ikidebir dönüşüm (cast) yapmalarına gerek kalmıyor. JDOM altında Java List ve Iterator kullanılıyor.

Genel kodlama hâtaları

Kod fazlalığı

Ufak şeyleri yapmak için fazla kod gerekiyor. Mesela, bir Attr düğümünün değerini kontrol etmek için 16 satır kod yazıldığını gördük. Bu tip şeyleri yapmak için 3 satırlık kod yetmeli. Tabii DOM'un soyutluk seviyesinin çok altta olması, yanlış bilinen kodlama teknikleri de bu problemi arttırdı.

DOM'u Dolaşmak

Baktığımız proje kodu içinde en çok yapılan işlem, DOM'u dolaşmak, ya da aramak idi. Ekte örnek bir kod görüyoruz. Bu kodda, 'baslik' adli bir dügüm noktasını belgeninin 'ayar' bölümünde arıyoruz.

Bu kod da yaptığımız, kök eleman ayarDugumu'nden başlıyarak, bu kökün ilk çocuğunu almak, ve bütün çocuklara teker teker bakmak. Gördüğümüz gibi, bayağı çetrefilli ve karmaşık bir kullanım, hata yapmaya çok açık.

Örnek olarak, ikinci satır getFirstChild (ilk çocuğu al) işlemi ile 'ayar' dügümünü getiriyor. Bu satırdaki problemlere bakalım. Aslında ilk çocuk dügümü aradığımız dügüm olmayabilir. Hiç kontrol etmeden ilk çocuğu alırsak, etiketin ismina aldırmamış oluyorum ve belgenin yanlış yerine sapmış olabiliyoruz. Çok başımıza gelen bir hata, mesela kök düğümünden sonra (enter) tuşu ile boş karakter ya da satırbaşı karakteri konulmuş ise olması; Bu durumda kökün altındaki ilk çocuk TEXT_NODE dügümü olur, aradığımız dügüm değil. Bunun deneyini siz de yapabilirsiniz; ornek.xml adlı dosyayı açip, örnek ve ayar etiket değerleri arasına bir satırbaşı koyun. Kodu işletince hata verip durduğunu göreceksiniz. Doğru işlem için bütün çocukları teker teker bakıp 'metin' olmayan türden olanını bulmam lazım.

Listing 1 altındaki kodun bir diğer problemi daha var. Eğer dosya yapısı beklediğimiz gibi değilse, mesela kök düğümün hiç çocuğu yok ise, ayarDugumu nesnesi null (boş) değeri taşıyacaktır, bu yüzden 3. satır hata mesajı verir. Bu yüzden kodun düzdün işlemesi için, hem dosyayı doğru gezmek için, hem her çocuk değerine teker teker bakmalıyım, hem de her işlemi çağırdığımda dönüş değerini kontrol etmeliyim. Değişik türden giriş verisini doğru işleyebilecek kod, detaya dikkat ve azami kod miktarı gerektirir.

Ve sonuçta, Listing 1'de gösterilen kod yerine tek bir getElementsByTagName adlı işlem yeterli olabilirdi, eğer programcı böyle bir arayüzün mevcut olduğunu bilse idi.

Etiket Altındaki Değeri Almak

Baktığımız projelerde, DOM dolaşımından sonra en çok ihtiyaç duyulan şey bir etiket altındaki değeri alıp getirmek olduğunu farkettik. Mesela elimizde Deger gibi bir dosya olsun. 'herhangibiretiket' etiketine geldikten sonra (dolaşım yaparak) altındaki metni nasıl alırız?

DOM düzgün olsaydı, şunu yapmak yetebilirdi:
etiket.getData();

Tahmin edebileceğiniz üzere, yukarıdaki işlem istediğimizi yapmıyor. Esas metin, etiket düğümü altında 'çocuk dügüm' olarak durmakta. Yani işleyen kod şöyle olmalı:
etiket.getFirstChild().getData();

İkinci örnekte bile şunu görüyoruz: Aradığımız değer ilk çocuk düğümde olmayabilir. Birkaç alt düğümden sonra olabilir. Arada boşluk karakteri olabilir. Doğru çözüm için bütün çocuklara bakıp Node.TEXT_NODE tipinde olanları aramamız ve birleştirerek sonuç değerini oluşturmamız gerekiyor.

JDOM kütüphanesi bu sorunu tek bir işlem ile çözmüş: getText. DOM Seviye 3 kütüphanesi de bu soruna getTextContent işlemi ile cevap verecek. Alınacak ders: Üst düzey arayüzleri alt düzey arayüzlere tercih edin.

getElementsByTagName

DOM Seviye 2 kütüphanesi, verilen bir etiket isminden, o etiket altındaki bütün çocuk düğümleri geri getirebilen bir işlem sunmuş. Mesela,
NodeList isimler = birEleman.getElementsByTagName("isim");
birEleman altındaki 'isim' adlı düğümleri NodeList nesnesi (listesi) içinde getirecek. Bu yöntem daha önce tartıştığımız yöntemlerden muhakkak daha rahat.

Fakat bu yönteminde problemleri var.

Problem söyle: getElementsByTagName işlemi bütün dosyayı özyineli bir şekilde dolaşıyor, ve uyan bütün düğümleri getiriyor. Farzedin ki, bir XML belgesi içinde müşteri, şirket ve ürün bilgisi taşıyorsunuz. Bütün bu bilgi çeşitleri içinde 'isim' adlı bir etiket taşiyabilir. İsim kelimesi sık kullanılan bir kelimedir. Fakat bu yüzden ürün ismi ararken, müşteri ve şirket isimleri geri alabilirsiniz. İsim aramsını bir alt-ağaç altında işletebilirsiniz, fakat XML'in esnek yapısı dolayısı ile bulduğunuz alt-ağacın yapısının tahmin ettiğiniz yapı olduğunu bilebilmek gayet güç.

DOM'u Düzgün Kullanabilmenin Yolları

DOM'un tasarım eksikleri olduğuna göre, programlarımızı yanlışsız yazabilmek için bazı prensipleri aklımızda tutmamız yararlı olur.

Prensipler


* DOM'u belge içinde gezinti (traversal) için kullanma
* Mümkün olduğunca belge gezintisi veya direk dügüm erişimi için XPath kullanın.
* DOM'un üzerinde kurulmuş ve DOM'u kolaylaştıran daha yüksek seviyeli bir kütüphane kullanın.

DOM gezintisi, hem çok lazım olan, hem de problem yarabilen bir şey. O zaman, belgeyi DOM kullanmadan nasıl gezeriz?

XPath

XPath XML belgelerinin belli bölümlerini uyumlama ile bulabilen, eldeki adresi ile direk erişebilen, ve tüm dosyayı arayabilen bir dildir. W3C kurumunun tavsiye ettiği bir metoddur, ve çoğu programlama dili altında ve XML paketleri içinde mevcuttur. Büyük bir ihtimalle XML paketiniz XPath'i ya zaten ya da eklemeli bir şekilde destekliyor.

XPath, 'yol simgelemi' denilen bir yöntem kullanır; Dosya sistemleri ya da Internet adresleri de aynı simgelemi kullanıyor. Mesela XPath dilinde /x/y/z yolu, x kök düğüm altındaki y düğümünün altındaki z düğümünü arar. Bu yol kalıbına uyan bütün düğümler bulunup getirilecektir.

Daha çetrefilli uyumlarda mümkündür. Mesela /x/y/* gibi bir komut x adlı herhangi bir yerdeki dügümün altındaki bütün y düğümleri geri getirecektir. /x/y[@name='a'] gibi bir kullanım, a değerini taşıyan ve x dügümü altında olan bütün y dügümlerini geri getirir. Dikkat edilmesi gereken, XPath boşluk karakteri gibi olayları bizim için doğru şekilde tetkikleyip, geriye istediğimiz değerleri getirmesi. XPath'in A'dan Z'ye bütün konularını işlemek için yerimiz müsait değil, Kaynaklar bölümünde daha fazla XPath bilgisi alabileceğiniz yerler var. Tavsiyemiz, XPath öğrenmek için biraz vakit ayırırsanız, mükâfat olarak daha basit ve düzgün XML işlemleri elinize geçecek.

Kaynaklar


* DOM Tarifnâmesi
* Bu yazının örnek kodları. CLASSPATH'inize Xerces and Xalan eklemeyi unutmayın.
* Apache projesinden Xerces and Xalan DOM ve XPath paketlerini indirebilirsiniz.
* JDOM projesi
* XPath belgeleri

Bu yazı ilk önce IBM developerWorks sitesinde yayınlanmıştır.

Tomcat ve Güvenlik

Aşağı yukarı her bilgi işlem uygulaması "sistem idarecisi" diye adlandırılabilecek kullanıcılar için özel bölgeler (sayfalar) tanımlar. Mesela, kullanici_ekle.jsp gibi bir sayfaya her kullanıcının girebilmesi güvenlik açısından tehlikeli olur. Bu sayfaları kullanıcı/şifre isteyerek korumamız gerekmektedir.

Tomcat üzerinde bunu yapmanın en basit yolu Realm (alanlar) fikrini kullanmaktır. Hatta eğer, kullacıya göre değişken türden sayfalara ihtiyacınız yok ise, isim/şifre ile sadece sayfaya "erişimi" kontrol etmek için Tomcat üzerinde kod bile yazmanıza gerek yok.

Kullanıcı Tanımlaması

TOMCAT_DIZINI/conf/tomcat_users.xml dosyasını metinyazar (notepad, emacs, vs) ile açın. Bu dosyada şu gibi veriler görebilirsiniz.

<tomcat-users>
<user name="tomcat" password="tomcat" roles="tomcat" />
<user name="role1" password="tomcat" roles="role1" />
<user name="both" password="tomcat" roles="tomcat,role1" />
</tomcat-users>


Bu isimler ve şifreler Tomcat ile beraber paketten çıkıyor. İsterseniz silebilirsiniz bile.. (Ama örnek oluşturması açısından tutsanız iyi olur). Şimdi, ali adında bir kullanıcıya bakıcı rolü vermek istersek,

<user name="ali" password="sifre123" roles="bakici" />

.. gibi bir satır yeterli olacaktır. Kullanıcı tanımlaması bu kadar!

Sayfa/Servlet Korumak

Şimdi, bir servlet'e erişim kontrolü getirelim.

site_dizininiz/WEB-INF/web.xml dosyasını açın, ve KorunacakBirServletIsmi adlı Servlet'inize sadece bakici rolünde olanların erişebilmesi için, şu ekleri yapın.

<security-constraint>
<display-name>skBakicisi</display-name>
<web-resource-collection>
<web-resource-name>skAdmin</web-resource-name>
<url-pattern>/servlet/KorunacakBirServletIsmi</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>bakici</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>

<login-config>
<auth-method>BASIC</auth-method>
<realm-name>sk</realm-name>
</login-config>

<security-role>
<role-name>bakici</role-name>
</security-role>




Bu kadar! Artık tarayıcınız ile http://localhost:8080/servlet/KorunacakBirServletIsmi sayfasını ziyaret ettiğinizde, isim ve şifreniz sorulacaktır. Bunun bir resmi aşağıda görülebilir.

Friday, October 31, 2003

Yapay Zeka ile Problem Çözümü

Baglanti

Oracle ve İşlem İdaresi

Veri tabanlarını kullanırken anlamamız gereken çok önemli bir kavram işlem (transaction) kavramıdır. Veri tabanı nedzinde işlemler, zamana bağlı olarak gelişirler, ve bu konuda işlemler, veri tabanına direk bağlı olan programların veriyi 'hangi zamanda, nasıl' göreceğini kontrol ederler.

Yani, dış dünyadan veri tabanının içine bakmamız bir işlem çerçevesinde gerçekleşir.


Üstteki resim ile işlemlerin nasıl kullanıldığını görüyoruz. Benzetme ile anlatmak gerekirse, bir işleme başlamak şuna benzer: Mesela veri tabanı bir apartman dairesi olsun, o zaman işleme başlamak, kişinin (kullanıcı) evin bütün odalarına (veriye) bakıp, akılda tutup, sonra bir odaya girmesidir. Bu odaya girince, kişi aklında olan bilgileri işleyip hakkında kararlar verebilir, vs.

O sırada, öteki odalarda ve de evin içinde yapılan kalıcı değişiklikleri göremez.

İşlem bitimi, Oracle COMMIT kelimesi ile olur, ve benzetmemizdeki kişinin odanın dışına çıkıp yaptığı değişiklikleri evin içine kalıcı olarak koymasına ya da, dısarıda yapılmış olanları görmesi demektir.

Buna işlemlerin kendilerini birbirlerinden 'izole' edebilme özelliği denir.

Kilit Sistemi ve İşlem Sınırları

Ayrıca, işlemlerin veri izolesi için kullanılmasına ek olarak, Oracle kilit sisteminin de işlem kavramında direk bağlandığını göreceksiniz. Yani,

SELECT * FROM CIZELGE1 WHERE DIZEY1 = '111' FOR UPDATE;

komutu sonucunda, DIZEY1 değeri 111 olan veri satırı (row) kitlenecektir. Bu satır, aynı bağlantı üzerinde COMMIT komutu verilene kadar kitli kalacaktır.

Aynı işlem sırasında kitli satıra erişmek isteyen öteki kullanıcılar, eğer yukarıdaki komutun AYNISINI işletirlerse, beklemede kalacaklardır.

Beklemeden geri dönmek istiyorlar ise, FOR UPDATE kelimesinden sonra NOWAIT (hiç bekleme) kelimesini eklemeleri gerekir.

İslem Ne Zaman Başlar?

Bir işlem, zaten bir işlem içinde bulunmuyorsanız, herhangi bir SQL komutuna kullandığınızda otomatik olarak başlayacaktır. Yani BEGIN TRANSACTION (işleme başla) gibi bir komuta gerek yoktur. Bir önceki işlemi COMMIT ile bitirdiyseniz, aynı bağlantı üzerindeki ilk SQL komutu otomatik olarak sonraki işlemi başlatır.

Gereğinden Fazla Calculus

(MİT üniversitesi Matematik hocası Gilbert Strang'in MİT üniversitesine hitaben bir yazısından alınmıştır)

Calculus I, Calculus II, Calculus III - öğretim sistemimizde ne kadar büyük bir dengesizlik! Matematiğin geri kalan kısmı Calculus tarafından boğuldu denebilir. Bu kadar Calculus dersinden sonra takip eden ders herhalde Türevsel Denklemler (gene Calculus), Calculus'tan önceki ders'te herhalde Calculus'a Giriş dersi idi. Arkadaşlar, bu dengesizliği düzeltmek bizim görevimiz, bunu başkasından bekleyemeyiz. Lineer cebir'in ne kadar önemli bir ders olduğunu biliyoruz. Bu ders seçmeli/rasgele alınan bir ders değil, uygulama olarak birçok öğrenciye Calculus'dan daha faydalı olacak bir ders. Artık sayısal bir dünyada yaşıyoruz.

Bu konu hakkında dünyadaki hocalara öncü ve örnek olmamızı istediğim için, Lineer Cebir'in faydalarından bahsetmek istiyorum. Özetle şöyle düşünüyorum: Eğer şu ankinden daha fazla öğrenci Lineer Cebir öğreniyor ise, matematik bölümü bir şeyleri doğru yapıyor demektir. İstatistik ve Ayrıksal Matematik te lazım. Umarım bölüm başkanı ve rektör onaylar. İnanıyorum ki bu sayede öğrencilerimi için doğru şeyi yapmış olacağız.

İzin verirseniz, lineer cebir ders basamaklarından bahsedeyim. Mesela dersin her aşaması belli denklemlerin çözümüne, ya da o denklemleri çözmeye temel olan fikirlere ve algoritmalara göre ayırılabilir. Bu safhalar birbirini tamamlamalıdır. Mesela 4 denklemi merkez olarak alabiliriz.
En önemli nokta, herhangi bir uygulama için (gerçek dünyada) bir doğrusal 'sistemi' görebilmek. Şu bizim ünlü A matrisimizi bulabilmek, tanımlayabilmek ne kadar önemli değil mi? Bunun sonrasında tabii ki o matris üzerinde işlem yapmamıza yardımcı olacak fikirler takip edecek.

* Alt-uzaylar ve bazlar, izdüşümler ve dikgenlik, özvektörler ve özdeğerler
* Algoritmalar da çok önemli (matris çarpımı da buna dahil)
* Ax = kolonların katışımı, A = LU ile yokedilmesi, sonra Gram-Schmidt işlemi

En mühim konu da 'doğrusal dönüşüm'. Eğer bir problem içinde matrisin bazına ne olduğunu biliyorsak, her şeyi biliyoruz demektir. Ben örneklere odaklanabilirim, siz ispatlara odaklanabilirsiniz, ama sınıfın ne beklediğine her zaman kulağımızı açık tutalım.

Tekrar ana konuya döneyim, çünkü hepimizin yardımını ve eylemini gerektiriyor. Lineer cebir hakkında çoğunlukla destek görüyoruz, ya da aldırmazlık görüyoruz. Öteki hocaların da kendi yapacak işleri var, hattâ ve hattâ üst düzey mühendisler bile lineer cebiri istenmeyen bir şey olarak görebiliyorlar. Belki de bilgisayarların işleri nasıl değiştirdiğinin farkında değiller. Fakat sonuçta öğrencileri önde tutarak doğru seçimi yapacaklardır. Öğrenciler durumu anladığında hocalarımız da doğru seçimi yaptıklarını inanacaklarına eminim.

Calculus I, II ve III derslerinin kendisinin reform edilmesi bu sunumun dışında. Bu dersler de önemli, ama hayat-memat seviyesinde değil. Öğrencilerin çoğuna 'yararlı' olacak türden matematik öğretmek bizim görevimiz.

Gilbert Strang

JDBC ile Tablo Karşılaştırmak

Bazen müşterimiz, bilgi işlem sisteminde çok önemli olarak görülen bazı bilgilerin 'değiştirilmesi' halinde bu olaydan haberdar olmak isteyebilir.

Genelde bu tip erişim problemleri için klasik çözüm, neyin değiştiğini raporlamak yerine, kullanıcı erişim haklarını kısıtlayan bir sistem getirmektir.

Fakat bazen sistem kullanıcıları özellikle erişim kısıtlamayı değil, neyin değiştiğini bilmek isteyebilirler. Müşteriniz, "bazı bilgilere erişmeye normal olarak hakkı olan kişilerin bile yaptığı değişikliklerden haberdar olmak istiyorum" diyebilir. Bu pek normal olmayan bir istek olsa da, mümkündür.

Bu teknik probleme, şu şekilde bir çözüm getirebilirsiniz.

Ya, değişimi görsel bazlı olarak görsel kod üzerinde yakalarsınız, ya da, değişimin nihai adresi olan veri tabanına inerek çıkartabilirsiniz.

Veri tabanına inerek yapabileceğiniz kontrollerin bir iyi tarafı şudur: JDBC genel veri bilgileri (meta data) denilen, bilgiyi tasvir eden bilgi sayesinde, bir veri tabanı içindeki tabloları ve onların kolon isimlerini genelci bir şekilde şekilde (metin bazlı) olarak toplamamız mümkün oluyor. Bu bilgileri kullanarak, veri tabloları içindeki veriye bile aynı genelci şekilde erişebilirsiniz. Yani, veri erişmek için yazdığınız kod, bir tablodan ötekine değiştirilmeden işleyebilir!

Özellikle değişim yakalamak gibi nerede bulunacağı bilinmeyen bir veri değişim arayışı, genelci bir yaklasımla çok daha yararlı olacaktır.

Ekte verilen TabloKarşılaştırıcı kodunda gördüğünüz gibi, herhangi bir tablonun 'öncesi' ve 'sonrası' karşılaştırmasının yapılması, bu tür bir yaklaşım ile çok kolay oluyor.

TabloKarşılaştırıcı

JSTL Yaratıcısı İle Mülakat

(JSL yaratıcısı Shawn Bayer ile mülâkattan alınmıştır).

Bize kendinizden ve şu anda uğraşmakta olduğunuz projeden bahsedermisiniz?

Yale üniversitesinde araştırmacı programcı olarak çalışıyorum. Bir şekilde Apaçe Yazılım Vakfı ve Java Birlik Süreci'ne dahil oldum. Şu anda JSP standart etiketleri (JSTL) teknolojisinin referans yazılım lideriyim. Bu yazılımı Java Birlik Süreci altında gerçekleştiriyoruz. Manning kitabevi altında 2 kitap yazdım; biri Web Development with JavaServer Pages, öteki JSP Standard Tag Library adlı kitap, yani JSTL.


JSTL Nedir?

JSTL, standart etiket kütüphanesidir. Bildiğiniz gibi, JSP altında anlık değişen türden içerik konabiliyor. Mesela programcık (scriplets) kullanabilirsiniz, ama herkesin bildiği gibi programcık ile sayfa yazdığımız zaman, içeriği işlem mantığından ayırmak zor oluyor. Sayfaya bakıyoruz, bir metin, bir Java kodu, tekrar HTML, tekrar Java, yani tam bir keşmekeş. Alternatif yöntem etiket kütüphaneleri, yani ihtiyaca özel (custom) etiketler idi. Etiket kütüphaneleri uzun süredir aramızdalar, değişik şirketler değişik kütüphaneler çıkardılar, Apaçe'den de bazı kütüphaneler geldi. JSTL atılımı bu bütün dağınık olan kütüphanelerin ortak bir temsilini çıkartıp standart bir etiket dilini ortaya koymak idi. Böylece, mesela içerik yazan görsel tasarımcılar tek bir etiket dili öğrenebilirler, ve her J2EE uyumlu servis ortamında kullanabilirler. Dil standart olunca, standarta uyan Uygulama Servisleri arasında bir rekabet çıkabilir, bunun sonucunda daha etkin yazılımlar ortaya çıkacaktır. Ya da, benim yazdığım gibi genel etiket konularında artık bir kitap yazılabilir, çünkü üzerinde mutabakat kurulmuş olan tek bir dil vardır.

JSTL JSR (Java Tarifname İsteği) ile Apaçe arasındaki ilişkiyi anlatabilir misiniz?

JSR süreci Java Birlik Süreci altındadır. Bütün öteki JSR'lar gibi (mesela J2ME, J2EE) birlik altındaki şirketler, uzmanlardan aldığı yorumlar ile ilerler. Benim yönettiğim Referans Yazılımı, Apaçe altında sürmekte. Yani JSTL tarifnamesinin 'gerçekleştirimi' Apaçe altında yapılıyor, aynen JSP/Servlet tarifnamesinin kodlamasının Apaçe altında Tomcat ile yapıldığı gibi. Yani ortada herkesin kodlama yapabileceği bir standart var, biz bu kodlamalardan sadece biriyiz. Ama referans olarak ilkiyiz. Standart kavramının güzel tarafı burada: Yazılımın gerçekleştirme safhası değişik şirketler tarafından yapılabileceği için, rekabet sayesinde daha çok iyi ürünler ortaya çıkabiliyor.

Apaçe'nin Sun ile özel bir ilişkisi var gibi gözüküyor... Bu ilişkiden biraz daha bahsedebilir misiniz?

Evet, hakikaten prensip olarak düşünürseniz Sun'ın JSTL için niye IBM ya da BEA gibi büyük 'ticari' şirketleri seçmediği biraz garip gelebilir. Fakat Apaçe'nin şimdiye kadar gerçekleştirmiş olduğu serbest yazılımlara bakarsanız, Apaçe Web Sunucusu ya da Tomcat gibi büyük, ve çok başarılı olmuş olan projeler görürsünüz, normal olarak bu yazılımlar etrafında büyük bir kullanıcı gurubu oluşuyor. Böyle bir kullanıcı gurubu, JSTL için uygun bir ortamdı zannediyorum. Ben bu kararın yapıldığı seviyede olmadığı için sadece tahmin edebiliyorum, fakat Apaçe etrafındaki kullanıcı gurubuna bir örnek vermem gerekirse; Şahsen Apaçe etiket kütüphanesi daha beta seviyesinde iken, etrafında birçok kullanıcı vardı. Ben de bu ilk kullanıcıların sorularını İnternet üzerinde cevaplıyordum, vs.. Tabii bu ileride yazacağım kitap için birçok soru/cevap topladım, yani böyle bir şeyi yapabilmem bile Apaçe etrafında nasıl büyük bir topluluk olduğunu gösteriyor.

JSTL amacı nedir, ve hangi problemleri çözmek için ortaya çıkmıştır?

Ee evet, daha önce belirttiğim gibi JSTL etiketlere bir standart getirmek görevini güdüyor, yani oluşum olarak şu an JSP teknolojisi ile alâkadar olan şirketlerin ve kullanıcıların ortak mutabakatını temsil ediyor. JSTL'in hedef gurubu sayfa içerik yaratıcısı, arka plan Java kodlayıcısi değil. İçerik yaratıcısı derken, belki de program yazmayı bilmeyen, ya da sayfa yaratırken program yazması gerekmemesi gereken kişilerden bahsediyorum. Ayrıca içerik yaratıcısı derken bir projede oynanan bir rolden bahsediyorum, özel bir kişiden değil. Genel hatları ile belirtmek gerekirse, JSTL, JSP'yi yepyeni bir guruba tanıştırıyor. Kitabımda örneklerini tekrar tekrar gösterdiğim gibi, aslında 'tamamen' JSTL kullanarak bütün bir uygulamayı baştan sona yazabilirsiniz. Tabii büyük bir yazılım ile uğraşıyorsanız bu kod bakımı açısından iyi bir mimari seçim olmayabilir, herhalde bu şekilde yazılım mimarları JSP içinde fazla işlem mantığı istemezler. Fakat teknolojinin bunu mümkün kılacak silahları 'sağladığını' belirtmek için bunu söyledim. Mesela kitabımda örnek olarak verdiğim bir portal uygulaması var. Ayrıca bir ileti sistemi, takvim, gibi örnekler var. JSTL çok esnek bir teknoloji, ve programcı olmayanlar için de yararlı. Programcı olanlar için bile yararlı bazı soyut temsiller bulunuyor. Hala arada sırada, bana içinde çalıştığım üniversiteden sayfa yazmam için istekler geliyor, o yüzden JSTL içindeki bu özellikler benim çok işime yarıyor.

JSTL'in ilginç bazı özellikleri nelerdir?

Tipik bir JSP uygulaması için lazım olan sorunların cevabı JSTL'de bulunabilir. Mesela, şartsal mantık için etiketler var. Ya da bir liste üzerinde döngü ile elemanları ziyaret edebilen sözdizim mevcut. JSTL, Java Collection arayüzünün sağladığı her nesne ile konuşup, elemanlarını ziyaret edebilir. JSTL'i metin formatlama için, ya da milletlerarası kişiselleştirme için kullanabilirsiniz. Veri tabanına direk erişebilen etiketler bile var; tabii bu özellik bazı ortamlarda tepki yarattı (sayfanın veri tabanına erişmesi kötü olarak bilindiğinden) fakat ufak ve orta ölçekli mimarilerde, ya da, içerik için gereken bazı bilgilerin bazen veri tabanında olması sebebiyle bu özelliğin olması bana göre iyi oldu. Mesela kullanıcının sayfasını kişiselleştirmesi sonucunda, ne bileyim, renk tercihi mesela veri tabanında olabilir. Bu gibi bir bilgiyi almak için bazıları koskoca bir katmandan geçmeden bu bilgiyi almayı tercih edebilirler.

Ayrıca JSTL, XML işlememiz için bile bazı etiketler içeriyor. Bu açıdan XSLT'ye rakip bile sayılabilir. Tabii JSTL, XSLT ile birbirini destekler halde de çalışabiliyor, mesela JSTL sayfası içinden XSLT değişimlerini tetiklemek gibi. Fakat buna ek olarak, XML içinden aranan metni çekip çıkartabilecek ve içerik üzerinde kullanabilecek JSTL etiketleri var. Böyle olunca, JSTL ile bir şablon oluşturuyorsunuz, sonra işte şuraya XML'den gelen bilgi döngü ile açılarak yazılabilir diyebiliyorsunuz, vs. JSTL üzerinde bütün bunları yapmamızı sağlayan bir deyim dili var. Kıyasla, JSP'yi programcı olmayanların kullanması çok zordu. Birazcık Java bilmeyenlerin JSP kullanması imkansıza yakındı. Mesela, oturum sınırı nedir, ya da istek nesnesi üzerinden bilgiyi nasıl alabilirim gibi.. JSTL deyim dili ile, Java bilmeden, sayfaya gelen bilgiye erişmeniz mümkün olabiliyor. İstek nesnesine erişmek için basit bir sözdizim yaterli oluyor. Deyim dili bütün etiketleri birarada tutan tutkaldır: Mesela bir etiket ile bir numarayı tarayıp, sonucu sınırsal değişken üzerine koyabilirsiniz, sonra başka bir yerde bu değere erişip başka bir işlem yapabilirsiniz.

XSLT'nin problemleri sizce nedir?

Şimdi belirteceğim görüş herkes tarafından ne kadar benimseniyor bilmiyorum ama, hafiften benim 'ufak' bir isyan çığlığım haline dönüştü. Çoğu kullanıcı için XSLT'nin kabul edilmez durumda. Zaten genelde işlevsel dilleri sevdiğimi söyleyemem, (XSLT bir işlevsel dildir). Akademik ortamda olmam yüzünden bu garip gelebilir, çünkü LISP ya da Scheme yerine gördüğünüz gibi Java'yı tercih ediyorum. Ama Java'nın başarısını bakacak olursak öteki insanlarda bu tercihi paylaşıyor demektir. Eğer bilgisayar dillerinin mimarisini biliyorsanız, şöyle bir tanım yapılabilir. Java ve JSP mecburi işlemsel bir dildir. "Şu, şurada, şu şekilde olacak" gibi tanımlar yapar. Işlevsel diller der ki "şu ve şu gibi kalıplar için, şöyle davran". Fakat problem şurada: İçerik üreten kullanıcılara bu kavramlar çok yabancı geliyor. Ayrıca, döngüler, koşulsal ibareler kullanamamak veriyi göstermemizi zorlaştırıyor.

Deyim dilinden biraz bahsedebilir misiniz?

Deyim dili, Java kullanmadan veriye ulaşmanın bir yoludur. İçerik üreticisi, Java'dan daha basit olan bu dili kullanarak sayfa yaratabiliyor. Javascript'ten ve alternatiflerinden bile daha basit. Her ortamın değişik bir deyim dili gerektirebileceğinden hareketle, bize bu deyim dilini nasıl seçtiğimizi soruyorlar. Bu soruya cevap, JSP'nin zaten kullanıldığı ortama en çok lazım olan deyim dilini bulduğumuz olacaktır. Yani, şu anda veriyi içerik olarak göstermesi gereken, ama Java programlamayı bilmesi gerekmeyen kimseler... Her lazım olan şey için yeni etiket deyim diline eklemedik, yeterli derecede bir alt sözdizim ile yetindik. Daha fazlası için zaten Servlet/JavaBean üzerinde birçok şey yapmak mümkün. Ya da özel etiket yazılabilir. Burada anahtar, mesela başkalarının yazdığı sayfaya bakım yapmak için çağırılabileceğiniz, böyle bir durumda herhangi bir dilin %20'sini bilmeniz yetmezdi. JSTL'in tamamı, bazı dillerin %20'sinden azdır. Mesela, oturum üzerinde olan kullanıcı nesnesinin adres değerine şöyle erişebilirsiniz: session.kullanici.adres ve etrafına $ işareti koyarsınız olur biter. Java ile session.getAttribute diyecektik, vs, tabii yanlış yapma ihtimali var, ve bir Java hatası olsa, içerikçinin hatayı düzeltecek Java'sı yok.

Ama sonuçta bir dili, başkası ile değiştirmiyor musunuz? Fark nerede?

Evet, sonuçta bütün diller ortak kavramları paylaşır. Fakat deyim dillerinin avantajı, işlem çağırma, Java tipleri, istisna hallerini bilmemize gerek bırakmaması. Örnek olarak, bütün istek (request) bildirgeçleri JSTL sayfasına String (metin) olarak gelir, eğer bu bilginin üst sınırlarını falan gösterecek olsak, bir sayı gerekir, vs, bütün bu dönüşümleri JSTL otomatik olarak yapar.

Bir şirket yazılımı içinde JSTL, genel mimari içinde nasıl yeralır?

JSTL, Java Collection arayüzlerini kullanmak için yazıldığı için, arka planda ne olduğu farketmez. Arkada Servlet, Bean'ler, ya da EJB olabilir, JSTL için bunlar önemli değildir. Model 2 MVC'ye bile JSTL rahatça uyabilir; Struts yakında JSTL'i içine dahil edecek. Herhangi ölçekte bir uygulama için JSTL kullanılabilir. Fakat belirteyim: JSTL'in özellikle küçük ve orta ölçek için kabul edilir olması için de özen gösterdik, bence Web uygulamalarında kronik gördüğüm bir sorun, üzerlerinde 'aşırı mühendislik' yapılmış olması.. Yani basit şeyler için muazzam çetrefilli tasarımların getirilmiş olması..



J2EE projelerinin en çok yaptığı hata nedir?

Benim özel görüşüm aşırı mühendislik büyük bir sorun. Çoğu internet ve şirket yazılımları, insanların anlaması için çok zor bir halde, ve bu büyük bir problem. Aşırı mühendisliğin en bariz kaynağı, vaktinden önce yapılmış eniyileştirme, yani, daha bir problem ortaya bile çıkmamışken o probleme göre tasarımlar yapmış olmak. Nesne havuzları (object pool) harika bir örnek. Her nasılsa, herhalde çok kötü olan örneklere bakarak, insanlar çok fazla nesne yaratıldığını görmüşler ve güya çöp toplama (garbage collecting) dayanılmaz bir problem. Ve bu sözde soruna çözüm olarak öteki metodlara bakmışlar, mesela veri tabanı bağlantısının havuzlanması gibi. Fakat bu öteki alanlardaki özkaynak gerçekten değerli, yani, veri tabanının az bir sayıda olan tavan bâglantı sayısı var canım! Bu nesne havuzcuları, gittiler nesneleri havuzladılar, bilmiyorlardı ki Sun'ın anında derleme teknolojisi yeni nesne yaratmakta çok hızlı. Sonuçta ne oldu, elimizde 'olmayan bir sorun' için eniyileştirilmiş bir kod var. Belki normalden 'azıcık' daha iyi performans gösteriyor, ama işte o kadar. O arada, kaynak kodun anlaşılması muazzam zorlaşmış, ve tabii ki bakımı bir o kadar zorlaşmış.

JSTL bir proje içinde işbölümü için nasıl faydalar getiriyor?

Genelde etiket kütüpleri, ve özellikle JSTL'in getirdiği fayda soyut kavramlarla oynayabilmektir. JSTL'in programcıklara olan üstünlüğü budur. Tabii bizim sektörün en önemli özelliği, soyutluk seviyesini kaldırarak işimizi azaltmak! (İdareciler de işi başkasının üzerine yıkarlar :) ). Sonuçta JSTL detayları, bu detayları görmesi gerekmeyen içerikçilerden saklayarak işlerini kolaylaştırır. Soyutlamanın ana fikri budur. Böylece proje içinde bazıları iş mantığı yazabilir, başka birisi bu mantığı nesne modeli üzerine koyabilir, ve bu model üzerinden gerekli bilgiyi Iterator nesnesi ile JSTL sayfasına afişe edebilir.

Servlet Teknikleri

Servlet nesnelerini JSP sayfalarının Javalaşmış hali olarak düşünebiliriz. Bir JSP sayfasının <% %> işaretleri arasında Java kodu yazmak yerine, aynı Java kodunu gerçek bir Java nesnesi olan Servlet üzerinde yaratıp, aynen orada çalıştırmak mümkündür. Zaten JSP sayfaları da derlenip, arka planda Servlet'e dönüşüyorlar!

Peki o zaman, ne için JSP kullanıyoruz? Nerede Servlet nerede JSP kullanalım?

Bu soruya cevap şöyle olacaktır: "Görsel kodları JSP içine, işlemsel kodları Servlet içine koymak gerekir".

İşlemsel kodlara örnek, veri tabanına erişen işlevler, hesap yapan, karar veren tanımlar, ya da, kullanıcının girdiği veriyi işleyip kontrolden geçiren türden işlemler olabilir. Servlet, bütün bu arka plan işleri yaptıktan sonra gerekli 'veri nesnelerini' yaratıp, kontrolü JSP'ye bırakabilir. JSP bundan sonra veri nesnelerine bakarak ekranda sayfayı göstermeye başlayacaktır.

Servlet, kullanıcı hareketlerinin (bağlantı tıklama, dügmeye basma) gittiği adres olmalıdır. Yani, bir url bağlantısı sayfaya koymuş isek, hedef olarak bu bağlantı, Servlet nesnesini gösterebilir. Bunu yapmak için şöyle bir ibare yeterlidir.

<a suraya="/IslemciServlet?bildirgec1=deger1&bildirgec2=deger2">Buraya Tiklayin</a>


Ya da, kullanıcının girdiği bilgileri işlemek için, HTML/JSP başında şöyle bir tanım yapabiliriz:

<form type=POST action="/IslemciServlet">
<input type...
....
<input type="submit"...
</form>


Yukarıdaki tıklamayı işlemek için, şöyle bir Servlet kodlanabilir.

public final class IslemciServlet extends HttpServlet {

// buraya, sinif icinde gerekli olan degiskenleri
// tanimlayabilirsiniz.

// tiklama islemi, bizi direk bu doGet islemine getirir
public void doGet(HttpServletRequest request,
HttpServletResponse response)

throws IOException, ServletException {

String bildirgec1 = request.getParameter("bildirgec1")
String bildirgec2 = request.getParameter("bildirgec2")

//
// bu degerler ile islem yap..
//

response.sendRedirect("sonuc_goster.jsp");

} catch (Exception e) {
throw new ServletException(e);
}



Sonuc_goster.jsp nesnesinin ekranda birseyler gösterebilmesi için, oturum nesnesi üzerine bazı cevap nesneleri koymak mümkün. Dikkat edin, Servlet, doGet işleminden return ile geri değer vermiyor. Servlet ile JSP'ler arasındaki iletişim bu yüzden, request.getSession() ile erişilen "oturum" (session) nesnesi üzerinden yapılıyor. Bu nesneye değer koymak için, şöyle bir ibare yeterli olur.

..
request.getSession().setAttribute("geriBildirgec1", new String("filan"));
..

Servlet Derlemek ve Yerleştirmek

Bağlantıların Servlet'lere erişebileceğini gösterdik. Peki Tomcat, ya da başka J2EE uyumlu Uygulama Servisi bu tanımı nasıl biliyorlar? Hangi Servlet'e nasıl erişileceğini bilgisayarda nasıl söylüyoruz?

Bunu yapmak için, site_ismi/WEB-INF/web.xml adlı dosyaya Servlet hakkında bilgi vermemiz gerekiyor. web.xml dosyası, Tomcat başlarken her seferinde "bakılan" bir dosyadır, Internet uygulamanız hakkında tanımlar burada yapılır.

<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
<servlet>
<servlet-name>IslemciServlet</servlet-name>
<servlet-class>IslemciServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>IslemciServlet</servlet-name>
<url-pattern>/IslemciServlet</url-pattern>
</servlet-mapping>

</web-app>




Uygulamanız için bir WAR dosyası paketlerken, yukarıdaki web.xml dosyasının WEB-INF/ dizini altında olması beklenir. J2EE standartına göre bu böyledir.

WAR dosyasının şöyle bir yararı var; İnternet uygulamanız için bütün gereken kodları bir paket içinde tutar. WAR dosyası yaratmak için JAR komutunu kullanabilirsiniz, sadece sonuç dosyasının sonu .jar ile değil, .war ile bitecek. Bütün fark burada.

Tabii WAR'ın 'formatı' bir yana, esas dikkat edilmesi gereken tarafı WAR'ın paketlediği 'dizin düzeninin' standarta göre olması gerektiğidir. Bu düzen şöyle olmalı:

site_ismi/WEB-INF/web.xml - Ayartanım dosyası
site_ismi/WEB-INF/classes - Derlenmiş Java nesneleri
site_ismi/WEB-INF/lib - Paketlenmiş serbest yazılım, ya da ticari dış
Java paketleri

Böyle bir düzeni paketleyip Tomcat'a verdiğinizde (webapps altına bırakarak mesela), hiç CLASSPATH ile uğraşmanız gerekmeyeceğini belirtelim. Bu yöntemin rahatlığı budur: J2EE standartına göre yazılmış bütün Uygulama Servisleri, classes/ ve lib/ altında gördükleri Java nesnelerini CLASSPATH'e otomatik olarak dahil ederler.

Servlet'e Dönelim

Web.xml, Tomcat'a Servlet'in nerede olduğunu gösterdi. Bunun haricinde, Tomcat'in içinde (server.xml üzerinde), her Servlet'i gösterecek şekilde yapılmış bir ayar da vardır. Bu ayar sayesinde sonu "Servlet" ile biten bütün Java dosyalarına, http://localhost:portno/siteismi/servlet/xxxServlet gibi bir ibare ile erişilebilirsiniz.

Yani, programcı dilerse, yukarıda servlet-mapping olarak gösterilen ibareyi hiç kullanmayabilir, Servlet'in öteki kullanım şekli ile halâ erişilmesi mümkündür. Seçim programcıya kalmış. Sistem idaresi bakımından Servlet'lerin direk adresini özellikle belirtmek size daha uygun gelebilir.

Evet, şimdi Tomcat'i başlatın, ve tarayıcınızdan önce HTML sayfasına, oradanda tıklayarak Servlet'i işlettirip, JSP sayfasına gidebilirsiniz.

Unutmayın, Servlet içinden HTML üretmeyin, çünkü kod bakımı açısından zorluklar yaşayabilirsiniz. Başkasının yazdığı bir program üzerinde Metin (String) nesnesi kullanılıp Java içinde HTML üretildiğini görünce kaçmak isteyen çok programcı gördüm! Aynı şekilde, JSP içinde görsel olmayan işlem yapmak uygun değildir. Sonuç itibari ile JSP içinde daha limitli bir ortama "hapis durumdayız", bir Java sınıfında olduğumuz kadar serbest olamayız. Bu yüzden dişli bütün kodların JSP içinden çıkartılması isabetli olur.

Özel örnek vermek gerekirse, birim testlerinin erişimi bakımından Servlet üzerinde işlem mantığı işinizi kolaylaştıracaktır. Ayrıca, kodunuz Servlet üzerinde ise, sözdizim hatalarını derleme sırasında bulabilirsiniz, JSP örneğinde sayfayı ayreten ziyaret ederek derleme işlemini 'tetiklemek' gerekecekti. Servlet ile bu dertlerden kurtuluyoruz.

Yardımcı Programlar


* Java J2SE Geliştirme Seti (JDK) - Temel Java kütüphaneleri ve derleyici programı
* Java J2EE Geliştirme Seti (JDK) - Servlet kodlarını derlemek için gereken kütüphaneler
* Tomcat Uygulama Servis programı

Unix Rsync - Makinelerarası Dosya Kopyalamanın Hızlı Yolu

Sitemiz için kullandığımız tekniklerden bir tanesi, geliştirme ortamında yaratılan içerik .xml, .class, .jpg, .gif kayıtlarından "sadece değişmiş olanların" sonuç ortamına kopyalanmasıdır. Kabul edersiniz ki, üst üste yapılan ve çok sayıda dosya içeren bu şekilde kopyalamalar için, sadece ve sadece yeni ve değişmiş dosyaların kopyalanması zaman bakımından en verimli seçenektir.

Sitemizin ilk başlangıç yıllarında kullandığımız Unix scp programı, her kayıtı sürekli sonuç ortamına kopyalıyordu. Örnek bir scp komutu aşağıda gösteriliyor.


scp *.jsp kullanici@bizim.isp.makinasi.com:/usr/local/site/dizin/

Rsync

SSH ve CVS ilgili makalede, ssh (ve dolaylı olarak scp) komutu ile, güvenli bir şekilde nasıl uzak herhangi bir makinada Unix komutu işletebildiğimizi görmüştük. SSH'in öngördüğü anahtar dosyalar doğru yerlere koyulduktan sonra,


ssh uzakmakina.com -l kullanici ls /usr/local/herhangibirdizin

..gibi bir komut, uzakmakina.com üzerindeki bir dizinin içeriğini dökebiliyordu! Hemde bunu yaparken, bildiğimiz Unix komutlarını uzaktaki bir makine üzerinde kullanabiliyorduk. Bu çok güçlü bir yöntemdir. Rsync programı da, arka planda kopyalamayı gerçekleştirmek için SSH'i kullanabiliyor. Güvenlik bakımından bu yöntemi seçmeniz tavsiye olunur.

SSH bağlantısı, rsync programına -e ssh ibaresini ile yapılıyor.

Aşağıda örnek bir rsync komutu görüyoruz.


rsync -av -e ssh /usr/local/dizin kullanici123@uzakmakina.com:/usr/local/filan/dizin

Bu komut, /usr/local/dizin dizini ile uzakmakina.com makinasındaki /usr/local/filan/dizin dizinini kullanıcı123 adlı kullanıcı üzerinden eşitliyor.

Not: Bu rsync komutunu ilk işlettiğinizde, bütün dosyaların bir kere kopyalandığını göreceksiniz (eğer sonuç dizini tamamen boş ise). Fakat ikinci sefer aynı rsync komutunu işletince, hiçbir kopyalanmanın olmadığını görmeniz mümkün olacak. Çünkü ikinci sefer rsync, akıllı bir şekilde hangi dosyaların değiştiğini ve eklendiğini anlamaya çalıştı, ve sadece farkları göndermeye çalıştı.

Kaynaklar

üzerinde kurmak için, rsync tar dosyasını cygwin dizininize (mesela c:/cygwin) bırakıp, tar xvf komutu ile açın.

Lokal Kopyalar İçin

Rsync'i iki diskiniz arasında yedekleme yapmak için de kullanabilirsiniz. Bu gibi durumlarda -e seçeneğine ihtiyacınız yoktur. Sadece -av ile rsync kullanmanız yeterli, mesela:


$ rsync -av  /cygdrive/c/Arsiv /cygdrive/f/Arsiv

Bu komut c: disk üzerindeki Arsiv dizinini f: adlı diske taşıyacaktır. Tabii, tekrar söyleyelim, rsync'in cp komutuna göre yararları şunlar; Aynen makinalararası durumda olduğu gibi, ilk kopyalama tamamlandıktan sonra "ikinci rsync" işlemi sadece farkları (birinci kopyalamadan sonra yeni olan dosyaları) gönderecektir. Bir diğer seçenek --delete ile de "hedef dizininde olup, kaynak dizininde olmayan dosyaları" bile otomatik olarak hedeften sildirebilirsiniz! Rsync mükemmel bir eşitleme aracıdır (synchronization tool).

Gördüğümüz gibi bu tür güçlü bir araç için tıklama ile "güzel gözüken" arayüzlü bir programı aramamıza hiç gerek yok. Unutmayın: Tıklamalar, tekrar işletilemez, bu yüzden admin'lerin korkulu rüyasıdırlar.

Eger cetrefil bir ssh kullaniyorsaniz, mesela ssh'e -P ile port vermeye mecbur kalmissaniz, vs

rsync --recursive -ve 'ssh -p [port]' /yerel/dizin kullanici@1.1.2.13:/uzak/dizin


Karesel Denklem Çözümünü Türetmek

Baglanti

Thursday, October 30, 2003

Oracle Kavramları

Oracle kurmak ve bakımını yapması gereken Veri Tabanı Sorumluları için, işe yarayabilecek bazı kavramlardan bahsetmemiz gerekiyor. Programcılar için de yararlı olacağını zannediyorum. Yazdığınız programın sonuç ortamında nasıl çalışacağı detaylı Oracle bilgisini gerektirebilir.

İyi bilmemiz gereken 3 kavram var. Şematik (schema), Çizelge alanı (tablespace), SID ve bu kavramların birbiri olan ilişkisi.

SID

'Veri tabanı' kelimesini kullandığımızda genelde birçok şeyden aynı anda bahsediyoruz. Oracle paket programının tamamına, içinde bilgi depolayan kayıtları, kullanıcı isimlerinin toplamina aynı anda veri tabani deniyor. Fakat, Oracle dunyasinda, bu kavramlari daha da berraklaştırmamız gerekecek. SID = Veri tabanı diyeceğiz, ve, veri tabanı Oracle paket programı değildir gibi bir tanım yapacağız.

Peki o zaman, veri tabanı nedir?

Oracle'a göre veri tabanı, hakkında konuşabileceğimiz en büyük kayıt birimidir. İçinde çizelgeler, onların yazıldığı dosyalar, bu çizelgelere erişecek kullanıcı isimleri, ve paraloların toplamına veri tabanı diyoruz. Bir proje icinde şu kelimeleri duyabilirsiniz.


* Hangi veri tabanına bağlandın, çizelge bilmemneyi bu tabanda bulamıyorum...
* Benim kullanıcı ismimi bu veri tabanında da yaratır mısın? Kullanıcı şifrem kabul edilmiyor
* Fazla veri tabanı yaratmaya gerek yok, bir tane üzerinde çalışsak olmaz mı?
* Hayır olmaz, çünkü veri tabanı idarecileri iki veri tabanı olursa idaresi kolaylaşır diyorlar.

Bunları tanımladıktan sonra, SID'e dönelim. SID, veri tabanına erişmemizi saylayacak bir isimden ibarettir. Örnek olarak SATIS, BORDRO, MUSTERI gibi veri tabanı isimleri olabilir.

Çizelge Alanı

Çizelge alanı, çizelgelerin üzerinde depolanacağı 'dosya' ismidir. Buna çok dikkat edelim. Dosya derken /usr/dizin1/dizin2/cizelge_alan_1.dbf gibi bir gerçek Unix dosyasından bahsediyorum. Yani, Oracle veri tabanının, gerçek dünya ile (işletim sistemi) buluştuğu yere çizelge alanı diyoruz.

Çizelge ile çizelge alanlarının bağlantısı, alan yaratılırken sâdece bir kere yapılır. Ondan sonra ne zaman bu çizelgeye erişseniz, önceden tanımlanmış olan dosyadan oku/yaz otomatik olarak yapıyorsunuz demektir.

Çizelge alanı yaratmak için, şöyle bir komut işletebilirsiniz.

CREATE TABLESPACE cizelge_alan_1 DATAFILE '/usr/local/dizin1/oracle/cizelge_alan_1.dbf' SIZE 200M;

Şematik

Şematik = kullanıcı diyelim, fakat Oracle dünyasında şematik biraz daha güçlü bir kavramdır. Eğer daha basit veri tabanlarına alışık iseniz, herhalde her kullanıcının, her çizelgeyi görmesine alışıksınız. Oracle için çizelgelerin erişilip erişilmeyeceği hem şematik bazında yapılmıştır, hem de, sahiplenme mekanizması yani, hangi çizelgenin kime 'ait' olduğu da şematik bazında yapılır. Bir veri tabanına (SID=ORNEK1) bağlandığınız zaman, tabanda bazı çizelgeleri göremeyebilirsiniz. Görmek için, belli bir şematik kullanarak bağlanmanız gerekecektir. Hattâ ve hattâ, aynı isimdeki iki çizelgeyi değişik şematiklerde yaratabilirsiniz; Oracle bundan yakınmaz. Yani, SID'den sonra Oracle'ı paylaştırmanın/bölmenin ikinci bir yolu şematik'tir.

Oracle idarecileri (yukarıdaki proje konuşmalarına o kadar aldırmayın) az miktarda SID ve paylaştırmak için çok miktarda şematik yaratmayı tercih ederler.

Şematik yaratmak için kullanıcı yaratmamız yeterlidir.

CREATE USER hasan IDENTIFIED BY hasanslx DEFAULT TABLESPACE alan1;

Ek Bilgiler

Kullanıcı MEHMET olarak SID'e bağlandıysanız, ve CREATE TABLE komutunu işletip bir çizelge yarattıysanız, bu çizelge MEHMET şematiğine ait olacaktır.

Bu çizelgeyi başkaları göremez. Görmesi için özel izin 'vermeniz' gerekir.

Eğer MEHMET kullanıcısı olarak bir çizelge yarattıysanız ve detay belirtmediyseniz, bu çizelge DEFAULT TABLESPACE diye yukarıda belirttiğimiz yokluk değeri (default) alan1 altında yaratılır.