Menu

9 Mayıs 2009 Cumartesi

Entity`de inheritance

Java Entity classları, Java Object Mapping teknolojisi sayesinde database deki tabloları oluşturmakta, bu da aslında object oriented ın nimetlerinden olan polymorphism’in nasıl tablolara yansıdığı sorusunu akla getirmekte. Teorik bilgim olmasına rağmen, bu yazımı yazarken bazı küçük testler yaparak teorik bilgimin ne kadar doğru olduğunu göreceğim.
Şimdi işe deneme amaçlı bir entity sınıfı yazarak başlayayım ve jpa daki default inheritance türü olan SINGLE TABLE ı incelemeye başlayalım.
AbstractEntity sınıfı
package Entities;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name="Abstract_Entity")
@Entity
public class AbstractEntity implements java.io.Serializable {

@Id
private Long id;

private String commonAttribute;


public String getCommonAttribute() {
return commonAttribute;
}

public void setCommonAttribute(String commonAttribute) {
this.commonAttribute = commonAttribute;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

}
yukarıda basit bir sınıf yarattım, bu sınıf diğer sınıfların “extend” edeceği, super sınıf. Annotation’larla default değer değiştirilmediyse jpa nın kullanacağı inheritance strategisi single table, şimdi diğer alt sınıfları da yaratalım.
package Entities;

import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.OneToMany;

@Entity
public class ATypeEntity extends AbstractEntity implements java.io.Serializable{
@OneToMany
private List attributes = new ArrayList() {};

public List getAttributes() {
return attributes;
}

public void setAttributes(List attributes) {
this.attributes = attributes;
}

}

package Entities;

import javax.persistence.Entity;
@Entity
public class BTypeEntity extends AbstractEntity implements java.io.Serializable{
private int bTypeEntityAttribute;

public int getBTypeEntityAttribute() {
return bTypeEntityAttribute;
}

public void setBTypeEntityAttribute(int bTypeEntityAttribute) {
this.bTypeEntityAttribute = bTypeEntityAttribute;
}
}
package Entities;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class AttributeEntity implements java.io.Serializable {
@Id
private Long id;

private String attribute;

public String getAttribute() {
return attribute;
}

public void setAttribute(String attribute) {
this.attribute = attribute;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}
}

ATypeEntity ile BTypeEntity AbstractEntity sınıfından türetildiler, yani AbstractEntity nin id ve commonAttribute değişkenleri her ikisinde de var. ATypeEntity nin bunun yanında one to many bir ilişkisi var, BTypeEntity nin ise kendine özel bTypeEntityAttribute adında bir değişkeni var.
Single Table stratejisinden beklediklerim!
Tüm bu ilişkileri tek bir tabloda toplamalı
Tablo içinde bir sütunla tablodaki satır’ın hangi objeye ait olduğunu söylemeli
  • Tüm sınıflar aynı tabloda tutulduğu için mesela BTypeEntity e ait bir değişken, ATypeEntity e ait bir satırda boş bırakılmalı.
Şimdi programı çalıştırıp, görelim

database schema
Yukarıda tam istediğim şekilde database yapısını oluşturdu. Bir kaç değer girdiğimde ise Dtype sütunun satırın ait olduğu objenin sınıfını belirtmek için kullanıldığını, diğer alanların ise boş kaldığını gördüm, böylece “single table” aslında tam beklediğim gibi çalısıyor.
Şimdi biraz bu strateginin avantajları dezavantajları üzerinde düşünelim,
Buradaki en büyük dezavantaj sınıfların sahip olmadıkları değişkenler içinde database de yer tutmaları ayrıca database deki satırların büyük boyutlu olması da iyi birşey değil. Ama yine de bu yöntem gayet basit ve tek satırla tüm bilgi alınabiliyor.
Not nullable sütunlar kavramı
Eğer her sınıfın değişkenleri tek tabloda tutuluyorsa, bir sınıf kendisine ait olmayan değişkenleri null yani boş olarak bırakıyor, bu durumda “not nullable” yani boş bırakılamaz değişkenler tanıtamıyoruz çünkü diğer bir sınıf kendisine ait olmayan bu değişken için “null” olarak tabloya girecek.
Simdi ikinci yönteme geçelim, “JOINED”
Burada yöntemimizi değiştirebilmek için tek yapmamız gereken, AbstractEntity sınıfına @Inheritance annotation ı ile strategimizi değiştirmek.
package Entities;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import  javax.persistence.InheritanceType;
import javax.persistence.Table;

@Table(name="Abstract_Entity")
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class AbstractEntity implements java.io.Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String commonAttribute;

public String getCommonAttribute() {
return commonAttribute;
}

public void setCommonAttribute(String commonAttribute) {
this.commonAttribute = commonAttribute;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

}

Şimdi benim JOINED strategisinden beklediklerim,
  • Her sınıfın ayrı bir tablosu olacak
  • Her sınıfın ayrı tablosunda sadece kendisiyle ilgili değişkenler tutulacak
  • Tablolar kendi aralarında JOIN sütunuyla ilişkilendirilecek.
Kodu çalıştırdığımda karşıma şu şekil bir database yapısı çıkıyor.

Database Schema Joined

Resimden görüldüğü gibi her sınıfın ayrı tabloları oluşmuş ve her tablo kendi sınıfıyla ilgili değişkenleri tutuyor. Bu yapıda mesela ATypeEntity sınıfına ait bir obje istendiğinde, AbstractEntity ve ATypeEntity e ait tablolar aralarında join yaparak bu obje oluşturulacaktır.

Bence bu yöntem object oriented mantığına daha çok uymakta, fakat her obje için join yapılmakta, eğer sınıflar arasında fark fazlaysa bence bu yöntem ilk yöntemimiz olan “single table” a göre daha uygun. Fakat her obje için sorgunun maliyeti joinlerden dolayı biraz fazla.

JPA nın inheritance için sunduğu son yöntem ise “Table Per Class” yani Türkçesiyle her sınıf için bir tablo. Bu yöntemden beklediklerim,
  • Tüm sınıfların ayrı tablosu olması fakat ayrıca bir sınıfa ait bir tablonun türediği sınıfa ait olup kendisine geçen değişkenler içinde yer tutmasıdır.
Burada aklıma gelen soru ise aslında eğer gerçekten her sınıfın tablosu üretilecekse bizim AbstractEntity sınıfınında tablosu üretilecek mi? Benim örneğimde soyut (abstract) bir sınıf değil ama gerçekte bu sınıfta soyut olabilirdi. Burada AbstractEntity sınıfını soyut sınıf yapıp, inheritance strategimi değiştirmeye karar veriyorum ki sorularım cevap bulabilsin ve kodumu aşağıdaki şekilde değiştiriyorum.
package Entities;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import  javax.persistence.InheritanceType;
import javax.persistence.Table;
@Table(name="Abstract_Entity")
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractEntity implements java.io.Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

private String commonAttribute;

public String getCommonAttribute() {
return commonAttribute;
}

public void setCommonAttribute(String commonAttribute) {
this.commonAttribute = commonAttribute;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

}

Table per class inheritance is not supported. Entity class [class Entities.AbstractEntity]. Hatasını alıyorum. Bu mesaj bana toplink in “table_per_class” ı desteklemediği izlenimine kapılıyorum. Yazımı burada sonlandırıyorum, çünkü elimde toplink ten başka jpa implementasyon paketi yok ve sorularım cevapsız kalıyor ne yazık ki.

7 Mayıs 2009 Perşembe

JAVA İLE .NET'İ KONUŞTURMAK

Bu yazımızda java ile basit bir web servisi yazıp .net ile bu servise erişmeyi anlatacağız.



Kullandığımız araç gereç ve platformlar:

1.) Sun Application Server 8.1

Download : http://java.sun.com/j2ee/1.4/download.html#sdk

2.) NetBeans IDE 4.1

Download : http://www.netbeans.org/downloads/index.html

3.) MySQL 4.1 ve MySQL Connector/J

Download : http://dev.mysql.com/downloads/

4.) Microsoft Visual Studio 2003

Download : http://msdn.microsoft.com/vstudio/



Java ile ilgili hemen heryerde karşılaşılan temel sorunları da bu yazı ile dile getirmeye çalışalım. Java ile başlangıç düzeyinde ilgilenenlerin en büyük sıkıntısı CLASSPATH ayarlarıdır ve bu sorunun hemen her kaynakta farklı çözümleri bulunmaktadır. Benim önereceğim çözüm de farklı olacak , çünkü önerdiğim Sun Application Server C:\Sun dizinine kendi JDK , J2EE ve JRE'sini kuruyor. Siz bu yazılımı yükleyerek aslında J2ME hariç komple Java Platformunu yüklemiş oluyorsunuz. Sun Java System Application Server'ı yükledikten sonra Bilgisayarım üzerinde sağ tuş -> Gelişmiş sekmesindeki ortam değişkenlerinde Sistem değişkenleri bölümünde yeni bir Sistem değişkeni tanımlayarak adına CLASSPATH diyelim ve Değişken değeri olarak aynen şunları yazalım : C:\Sun\AppServer\jdk\bin;C:\Sun\AppServer\jdk\jre\bin;C:\Sun\AppServer\jdk\jre\lib;C:\Sun\AppServer\jdk\jre\lib\ext;C:\Sun\AppServer\jdk\jre\lib\ext;C:\Sun\AppServer\jdk\bin;C:\Sun\AppServer\lib



Bu ortam değişkenleri Java'nın ihtiyaç duyduğu bütün kitaplıkları yükler. Daha sonra siz istediğiniz veritabanı sürücüsünü burada belirtilen C:\Sun\AppServer\jdk\jre\lib\ext dizinine atarsınız ve bu dizin tanımlı olduğu için veritabanı sürücünüz de uygulamalarınız tarafından çalıştırılabilir.Dolayısıyle MySQL sürücüsünü de bu dizine koplayamanız gerekiyor.



Veritabanı, uygulama sunucusu ve web servisi için Java idelerinin belki de en başarılısı olan NetBeans dışında herhangi birşeye ihtiyacımız bulunmuyor , ancak bu IDE'de Java ile ilgili bütün işlerimizi yapabilmek için bazı tanımlamalar yapmamız lazım.



Önce Sun Application Server'ı NetBeans'e tanıtmamız gerekiyor. Bunun için Tools -> Server Manager yolundan giderek Açılan Server Manager Penceresinde AddServer diyelim. Gelen pencerede admin kullanıcı adı ve parolasını yazdıktan sonra Sun Application Server artık NetBeans IDE ile bütünleşik çalışmaya başlayacakıtır.







MySQL sunucusunu NetBeans IDE'ye tanıtmak için de benzer bir yol izliyoruz.Sol taraftaki Runtime arabiriminde bulunan Databases bölümündeki Drivers'e sağ tuş ile tıklayıp Add Driver komutu veriyoruz. Gelen pencerde Add bunonuna tıklayarak C:\Sun\AppServer\jdk\jre\lib\ext\ yolunda bulunan mysql-connector-java-3.1.10-bin.jar driverını gösteriyoruz.

Dikkat : Bu sürücü dışındaki sürücüler MySQL 4.1'de Türkçe karakter problemi çıkarıyor.Bu sürücü ile MySQL character set'inizi latin5 olarak ayarlayabilirsiniz.







MySQL sürücüsünü tanıttıktan sonraki durum







Bu aşamalardan sonra şimdi bilgisayarımızda kurulu bulunan MySQL sunucusuna bağlanmamız gerekiyor. Bu işlem için Databases/Drivers/MySQL(MM.MySQL driver) bölümünde sağ tuş ile Connect Using komutu verelim.







Artık btturk isimli bir veritabanımız var ve bu veritabanında NetBeans ile bilgiler isimli bir tablo oluşturabiliriz.













Evet bilgiler isimli tablomuzu oluşturduk ve içerisine okuyacağımız verileri de yazdık.Şimdi web servisimizi yazmaya başlayabiliriz.Web servisi için önce bir web uygulaması projesi başlatmamız gerekiyor. NetBeans menüsünden File -> New Project yolunu izliyoruz.Projemiz bir web uygulaması ve adı da webServisiDeneme1









Projeyi oluşturduktan sonra Web Servisinin çalışacağı java package'ı oluşturmamız gerkiyor.İşlemin nasıl yapıldığı resimlerde görülebilir.









WebServisi isimli package'i oluşturduktan sonra bir web servisi yaratabiliriz.Bu işlem ekran görüntüleriyle gösterilmiştir:









Personel Web Servisini oluşturduktan sonra servis üzerinde sağ tuş->Add Operation... komutu veriyoruz.







Operasyonumuz sonucunda bize personel bilgilerinin String türünden dönmesini istediğimiz için Return Type'ı String olarak seçiyoruz.







Parametre olarak göndereceğimiz değerin veritabanındaki id alanına denk gelmesi nedeniyle parametre ekleme işleminde int değer göndermemiz gerekiyor. Bu işlem için Add Operation penceresinde Add tuşuna tıklayarak parametre tipi olarak int ve parametre ismi olarak id yazıyoruz. Web servisimiz çalıştığında oluşacak WSDL dökümanında bu değerler gidip gelecektir.







Bu işlemlerden sonra projemizin görüntüsü aşağıdaki gibi olacaktır:







Şimdi SQL bağlantımız için gerekli kodları yazabiliriz :

Yeni bir java class oluşturarak adını SQLSorgulari verelim ve içerisine şu satırları yazalım :



package WebServisi;

import java.sql.*;

public class SQLSorgulari {



public SQLSorgulari() {

}



public String bilgiDondur(int id) throws Exception{

Class.forName("org.gjt.mm.mysql.Driver");

java.sql.Connection baglanti = DriverManager.getConnection("jdbc:mysql://localhost/btturk","root","");

java.sql.Statement sorgulama = baglanti.createStatement();

java.sql.ResultSet veriler = sorgulama.executeQuery("SELECT * FROM bilgiler where id="+id);

String bilgiler=null;

while (veriler.next()){

bilgiler = veriler.getString(1)+" "+veriler.getString(2)+" "+veriler.getString(3);

}

return bilgiler;

}



}



Bu sınıf sadece SQL sorgusu sonucunda dönecek değer için bağlantıları sağlamakta ve bilgiDondur() metodunu yazmaktadır bu metodun tek yaptığı kendisine gelen int türünden değeri veritabanında aramak ve String türünden bir veri döndürmektir. Buna benzer java veritabanı örnekleri heryerde bulunabileceği için üzerinde fazla durmuyoruz. Asıl işimiz PersonelImpl.java ile. Bu sınıftan bilgiDondur metodumuzu çağırmamız gerekiyor. Web servisini oluştururken iki dosya oluşmuştu biri PersonelImpl.java ve diğeri PersonelSEI.java bu iki dosyadan PersonelSEI.java sadece PersonelImpl.java sınıfındaki metodları java.rmi ile sunma işi yapmaktadır.Asıl metodun tanımlama yeri PersonelImpl.java'dır ve buradan SQL medodumuzu çağırmamız gerekiyor.



PersonelImpl.java sınıfına gidip aşağıdakileri yazalım :



package WebServisi;

//SQL metodumuzu barındıran sınıfı çağırıyoruz

import WebServisi.SQLSorgulari;

public class PersonelImpl implements PersonelSEI {



SQLSorgulari SQLSorgu= new SQLSorgulari();//SQLSorgulari isimli sınıfın bir örneğini yarattık



public String bilgiGetir(int id){

try{

return SQLSorgu.bilgiDondur(id);//bilgiDondur isimli metodu çağırıyoruz

}catch(Exception hata){

return "hata";

}

}



Web servisimiz tamam artık uygulamayı run edebiliriz. F6 tuşuna basarak uygulamayı çalıştırıyoruz. Bu esnada uygulama derlenmekte, WAR dosyası olarak birleştirilmekte ve uygulama sunucusunda deploy edilmektedir. Browser'ımızı açıp http://localhost:8080/webServisiDeneme1/Personel?WSDL yazarsak çalışan web servsinin WSDL dökümanını görebiliriz.







Şimdi Java ile web servisimizi yazdık ve bunu .NET içerisindeki bir uygulamadan kullanmamız gerekiyor. Bu iş için Visual Studio açmak gerektiği için NetBeans'i ve bilimum açık programınızı kapatmanızı öneriyorum çünkü zaten Sun Application Server epey fazla RAM tüketiyor.Yalnız dikkat edilmesi gereken nokta şu ki eğer Sun Application Server'ı NetBeans üzerinden Start ettiyseniz NetBeans'i kapattığınızda Sun Application Server de kapanacaktır. Böyle bir durumda Başlat->Programlar->Sun Microsystems->Application Server PE ->Start Default Server ile uygulama sunucusunu yeniden çalıştırmanız gerekebilir.



Eski ve daim dostumuz Visual Studio 2003 'ü açıyoruz ve yeni bir proje oluşturuyoruz.Projenin adı da JavaDotnet ve bu bir Visual Basic .NET projesi. Aslında uygulamayı C# ile de yazabilirdik fakat o zaman Java ile Java konuşuyormuş gibi bir durum ortaya çıkabileceği için iki farklı teknolojinin daha iyi farkedilmesini sağlamazdı.







Oluşturduğumuz uygulamaya iki label ve iki metin kutusuyla bir de buton ekliyoruz.







Web Servisimizi .Net projesine bir Web Referansı olarak ekliyoruz .







Görüldüğü gibi Web Servisimiz ve bilgiGetir() metodumuz Visual Studio tarafından görüldü.







Web Referansını ekledikten sonra projemize geri dönüyoruz ve Web Servisi nesnesinin örneğini oluşturuyoruz. Ben bu örneği public olarak tanımladım ama genelde örneklerde tıklama olayının (event'ın) içinde Dim ile tanımlandığını görüyoruz. Bu web servisinin bize sağladıklarını başka form elementlerinde kullanmak gerekebileceği için bence bunu bir üst scope'ta tanımlamak daha iyi.







Yine bir nesnenin bizden neler isteğini ve bize ne vereceğini görmenin en iyi yolu olarak iki öneri sunabilirim . Biri WSDL dökümanını incelemek bir diğeri de örneklediğimiz nesnenin metod veya özelliklerini anlamak için yanına bir nokta koymak. Örneğimiz için gösterecek olursak :





personel nesnemizin bilgiGetir metodu bizden localhost.bilgiGetir türünden bir değişken istiyormuş ve karşılığında da localhost.bilgiGetirResponse tipinde bir yanıt döndürüyormuş.O halde bizim bu tipten değişkenler oluşturmamız gerekiyor. Biz de bu değişkenleri tanımlıyoruz :



Public personel As New localhost.Personel

Public bilgiGiden As New localhost.bilgiGetir

Public bilgiGelen As New localhost.bilgiGetirResponse



Butonun tıklama olayına aşağıdakileri yazdığımızda uygulamamız çalışacaktır :



Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim texteYazilan As Integer = CType(TextBox1.Text, Integer)

bilgiGiden.int_1 = texteYazilan

bilgiGelen = personel.bilgiGetir(bilgiGiden)

TextBox2.Text = bilgiGelen.result

End Sub



5 Mayıs 2009 Salı

Java Persistence API

Java persistence api java geliştiricilerine uygulamalarında kullanacakları veriye nesne
göreli olarak erişim imkanı sunar. Java persistence üç ana alana ayrılır:
• Java Persistence API
• Java sorgu dili
• Fiziksel veriyi nesne gцreli eşleme
1- Entity
Entity java persistence ın tanım nesnesidir. Genel olarak Entity göreli veri tabanında
tablolara karşılık gelir ve her Entity örneği bu tabloda bir satırı ifade eder. Bir varlığın
persistent durumunu Entity ilgili alanları yada özellikleriyle belirlenir. Bu alanlar ve
özellikler Entity belleklerde tutulan verilerle eşlenmesi için nesne/göreli eşleme
yöntemlerini kullanırlar.
1.1- Entity Sınıflarının Gereksinimleri
Bir varlık sınıfı şu gereksinimleri izlemelidir:
• Sınıf javax.persistence.Entitiy bilgilendirmelerine uymalıdır.
• Sınıfın public veya private argümansız bir yapılandırıcısı olmalıdır. Sınıfın
bunun dışında başka yapılandırıcıları da olabilir.
• Sınıf final tanımlanmamalıdır. Hiçbir metot ve persistence bağımlı değişken
final tanımlanmamalıdır.
• Eger sınıfın bir kopyası ayrı bir nesne gibi bir değer olarak atanmak isteniyorsa
bu sınıf Serializable ara yüzünü gerçekleştirmelidir.
• Entity sınıfları hem Entity sınıflarını hem de diğer sınıfları extend edebilir. Diğer
sınıflar da varlık sınıflarını extend edebilirler.
• Persistence ilişkili değişkenlerin tümü private, protected yada paket içi private
olarak tanımlanmalıdır ve direk erişimleri sınıf içi metotlarla olmalıdır.
1.2- Entity Sınıfında Persistence İlişkili Alanlar ve Özellikler
Entity persistence durumu o Entity değişkenleri veya JavaBeans-style özellikleri
tarafından erişilebilirdir. Bu alanlar ve özellikler şu türlerde olmalıdır:

• Java İlkel Türleri
• Java.lang.String
• Diğer Türler:
o Java.math.BigInteger
o Java.math.BigDecimal
o Java.util.Date
o Java.util.Calendar
o Java.sql.Date
o Java.sql.Time
o Java.sql.TimeStamp
o Kullanıcı tanımlı türler
o byte[]
o Byte[]
o char[]
o Character[]
• Sayılı türler
• Diğer Entity ve/veya Entity grupları
• Gömülü sınıflar
1.2.1- Persistent Alanlar
Eger Entity sınıfı persistent alanlar içeriyorsa, Persistence çalışma zamanı
Entity sınıfı değişkenlerine doğrudan erişebilir.
1.2.2- Persistent Özellikler
Eger Entity sınıfı persistent özellikler içeriyorsa, Entity JavaBeans in metot
çevirimlerini takip etmelidir. JavaBeans-style özellikleri getter ve setter methodları
kullanır. Bu metotların isimleri Entity sınıfının değişken isimlerinden sonra tanımlanır.
Her özellik için bir getter (getProperty) ve setter (setProperty) bulunur. Tek değerli
özellikler için method şekli şöyledir:
Type getProperty()
void setProperty(Type type)

Entitylarda Birincil Anahtarlar

Her Entity bir tek nesne tanımlayıcısına sahiptir. Örneğin bir tüketici Entityı
tüketici numarası ile simgelenir. Birincil anahtarlar istemcilerin ilgilendikleri Entity
nesnesine ulaşmalarını sağlar. Her Entityın bir birincil anahtarı olmak zorundadır. Bir
Entity basit yada bileşik birincil anahtara sahip olabilir. Basit birincil anahtarlar
javax.persistence.Id notasyonunu kullanırlar. Bileşik birincil anahtarlar bir birincil
anahtar sınıfında tanımlanmalıdır. Bileşik birincil anahtarlar
javax.persistence.EmbeddedId ve javax.persistence.IdClass notasyonlarını
kullanırlar.
Birincil anahtarlar veya bileşik anahtarların özellik yada alanları şu türleri
kullanmalıdır:
• Java İlkel Türleri
• Java.lang.String
• Java.util.Date
• Java.sql.Date
Kayan noktalı gösterim birincil anahtarlar için asla kullanılmamalıdır.
1.3.1- Birincil Anahtar Sınıfları
Bir birincil anahtar şu özellikleri karşılamalıdır:
• Sınıfın erişim tanımlayıcısı public olmalıdır.
• Цzellik tabanlı erişim kullanılıyorsa sınıfın özellikleri public yada protected
olmalıdır.
• Sınıfın bir public yapılandırıcısı olmalıdır.
• Sınıf hashCode() ve equals(Object other) metotlarını gerçekleştirmelidir.
• Bileşik birincil anahtarlar çoklu alan ve özelliklerle eşleşmiş olarak yada
gцmьlebilir sınıf şeklinde ifade edilmelidir.
• Eger birincil anahtar sınıfı bir Entityın alanları yada özellikleriyle eşleşmişse,
birincil anahtar sınıfının özellikleri ve alanlarının isimleri ve türleri o Entity
kümesinin isimleri ve türleriyle uyuşmalıdır.


Varlıklarda Çokluk Bağıntısı

Entitylarda 4 çeşit çokluk vardır. Bire bir, bire çok, çoğa bir ve çoğa çok.
Bire-bir ilişki : Her Entityın bir özelliği başka bir bağıntının sadece tek bir özelliği ile
eşleştirilmişse bire bir ilişki vardır denir. Bire bir ilişkiler javax.persistence.OneToOne
biçimini kullanırlar.
Bire-çok ilişki : Bir Entityın bir özelliği bir başka Entityın birden fazla alanı ile
ilişkilendirilmiş olabilir. Bire çok ilişkiler javax.persistence.OneToMany biçimini
kullanırlar.
Çoğa-bir ilişki : Bir Entityın birçok özelliği bir başka Entityın yalnız bir alanı ile
ilişkilendirilmiş olabilir. Bu durumda çoğa bir ilişki vardır denir. Çoğa bir ilişkiler
javax.persistence.ManyToOne biçimini kullanırlar.
Çoğa-çok ilişki : Bir Entityın birçok özelliği bir başka Entityın birden fazla alanı ile
ilişkilendirilmişse çoğa çok ilişkiden söz edilir. Çoğa çok ilişkiler
javax.persistence.ManyToMany biçimini kullanırlar.
1.5- Varlık Bağıntılarının Yönü
Varlıklar arası ilişkiler iki yönlü yada tek yönlü olabilir. iki yönlü ilişkiler hem sahip
taraf hem de ters tarafa sahiptir. tek yönlü ilişkilerde ters taraftan söz edilmez,
yalnızca sahip taraf vardır. Persistence ın ilişkiye dair günlemeleri veri tabanında
nasıl yapacağı sahip tarafa bağlıdır.
1.5.1- İki Yönlü İlişkiler
İki yönlü ilişkilerde her Entityın başka bir Entitya ilişkin alan yada özelliği
bulunur.
İki yönlü ilişkiler şu kurallara uymalıdır:
• İlişkinin ters tarafı mappedBy elemanı kullanılarak sahip tarafa ait olmalıdır.
• Çoğa çok ve çoğa bir ilişkilerin çok tarafları mappedBy elemanı tarafından
tanımlanmamalıdır. Çok taraf her zaman sahip taraf olmalıdır.
• Bire bir iki yönlü ilişkilerde sahiplik yabancı anahtara sahip olan tarafa aittir.
• Çoğa çok ilişkilerde her iki yön de sahip taraf olabilir.


1.5.2- Tek Yönlü İlişkiler
Tek yönlü ilişkilerde yalnızca bir varlığın ilişki alanı yada özelliği bulunur. İlişki
alanı bulunan Entity ilişkili olduğu varlıktan haberdardır fakat ilişkili olunan Entityın
ilişki alanı olan Entitytan haberi olmaz.

2- Entity Manager

Varlıklar Entity Manager tarafından yönetilirler. Entity Manager
javax.persistence.EntityManager örnekleriyle ifade edilir. Her bir Entity Manager
örneği persistence bağlamlarıyla birleşirler. Persistence bağlamının görev aralığının
içinde varlık örneklerinin yaratılması , üstelenmesi ve silinmesi bulunur.
2.1- Persistence Bağlamı
Persistence bağlamı, yönetilen varlık örneklerinin oluşturduğu bir yapıdır ve bu
yapı özel bir veri tabanında bulunur.
2.2- Entity Manager
Varlık yöneticisi, varlık örneklerini yaratır ve yok eder. Ayrıca, varlıkları temel
anahtarına göre bulur ve sorguların bu varlıklara uygulanmasını sağlar.
2.2.1- Entity Manager Denetleyici Yönetimi
Herhangi bir varlık yöneticisinin persistence bağlamı denetleyici kullanarak
otomatik olarak çoğalır. Uygulamanın tüm bileşenleri tarafından kullanılan varlık
yöneticisi örneği Java Transaction Architecture (JTA) denilen işlemin içinde bulunur.
JTA işlemi diğer uygulamanın bileşenlerini de işin içine sokar. Bu JTA
işleminin bileşenleri persistence bağlamına erişmek ister. Bunun olması için varlık
yöneticisinin javax.persistence.PersistenceContext aracılığıyla uygulama
bileşenlerine enjekte edilmesi gerekir. Persistence bağlamı JTA işlemi sırasında
otomatik olarak artar ve varlık yöneticisi bu JTA işlemi sırasında Persistence bağlamı
ile aynı persistence parçasını işaret eder. Bu sayede uygulamanın bileşenleri varlık
yöneticisine parametre geçmek zorunda kalmaz sadece JTA işleminde değişiklik
yapmak yeterlidir. Java EE denetleyicileri buradaki yaşam döngüsünü yönetirler.
Entity Manager örnekleminin uygulama bileşenlerine enjekte edilmesi:

@PersistenceContext
EntityManager em;
2.2.2- Entity Manager Uygulama Yönetimi
Persistence bağlamı uygulamanın bileşenlerinde otomatik olarak artmıyorsa
ya da varlık yöneticisinin yaşam döngüsü uygulama tarafından yönetiliyorsa bu
durum ortaya çıkar.
Entity Manager bir uygulama tarafından persistence bağlamına erişmek için
kullanılıyorsa ve JTA işleminde tarafından artırılmıyorsa kullanılır. Başka bir deyişle
Entity Manager yeni ve izole olmuş persistence bağlamını oluşturur.Entity Manager
ve onun yarattığı persistence bağlamı uygulama tarafından yaratılır ve yok edilir.
Uygulamalar javax.persistence.EntityManagerFactory metodunu kullanarak
varlık yöneticisini oluşturur.

@PersistenceUnit
EntityManagerFactory emf;

EntityManagerFactory örneklemi kullanarak varlık yöneticisi oluşturulur.
EntityManager em =emf.createrEntityManager();

2.2.3- Entity Manager Kullanarak Varlıkları Bulmak
EntityManager.find metodu kullanarak varlık biricik anahtarına göre
depolanmış varlıkları buluruz.

@PersistenceContext
EntityManager em;
public void enterOrder(int custID, Order newOrder) {
Customer cust = em.find(Customer.class, custID);
cust.getOrders().add(newOrder);
newOrder.setCustomer(cust);
}

2.2.4- Entity Örneklem Yaşam Döngüsünün Yönetimi
Entitylar üstündeki işlemleri varlık yönetici kopyalarıyla yönetiyoruz. Entity
örneklemleri 4 durumda bulunabilir: yeni , yöneten , silinen ve ayıran durumlar.

Yeni Entity örneklemlerinin persistent kimlikleri yoktur ve Entity bağlamıyla
ilişkendirilecek durumda değillerdir.
Yöneten Entityk örneklemlerinin persistent kimlikleri vardır ve Entity
bağlamlarıyla ilişkilendirilirler.
Ayıran Entity örneklemlerinin persistent kimlikleri vardır ve Entity bağlamıyla
ilişkendirilecek durumda değillerdir.
Silinen Entity örneklemlerinin persistent kimlikleri vardır ve Entity bağlamlarıyla
ilişkilendirilirler
2.2.4.1- Entity Örneklemleri
Yeni Entity örneklemleri persistent metodu tarafından yönetilirler. Yani persist
metodu tamamlanmış işlem gerçekleştiği zaman Entityın bilgileri bir veri tabanında
saklanır.
@PersistenceContext
EntityManager em;
...
public LineItem createLineItem(Order order, Product product,int quantity) {
LineItem li = new LineItem(order, product, quantity);
order.getLineItems().add(li);
em.persist(li);
return li;
}

@OneToMany(cascade=ALL, mappedBy="order")
public Collection getLineItems() {
return lineItems;
}

2.2.4.2- Entity Örnekleminin Silinmesi
Entity örneklemlerinin yönetiminde silme işlemini yapmak için silme metodunu
kullanırız ya da cascade silme işlemini kullanırız. Bunu birebiriyle ilişkili Entitylarda
kullanırız. Eğer bu silme metodu yeni bir Entity tarafından çağırılıyorsa bu komut
askıya alınır. Eğer silme metodu Ayıran bir Entity tarafından çağırılıyorsa bu bir hata
oluşmasına sebep olur ne IllegalArgumentException fırlatır.

Public void removeOrder (Inteder orderId){
try {
Order order =em.find(Order.class,orderId)
em.remove(order);
}
}
2.2.5- Sorguların Oluşturulması
EntityManager.createQuery ve EntityManager.createNamedQuery metotları
Java Persistence sorgulama dillerindeki sorgulamaları kullanarak saklanmış bilgileri
sorgulamak için kullanılır.
CreateQuery metodu dinamik sorgular yaratmak için kullanılır.
public List findWithName(String name) {
return em.createQuery(
"SELECT c FROM Customer c WHERE c.name LIKE :custName")
.setParameter("custName", name)
.setMaxResults(10)
.getResultList();
}
CreateNamedQuery metodu ise statik sorgular yaratmak için kullanılır. Bu sorgular
javax.persistence.NamedQuery de tanımlıdır.
@NamedQuery(
name="findAllCustomersWithName",
query="SELECT c FROM Customer c WHERE c.name LIKE
:custName"
)
Alt tarafta createNamedQuery metodunun kullanımına ait bir örnek var. Bu örnekteki
NamedQuery yukarıda tanımlanmıştır.

@PersistenceContext
public EntityManager em;
...
customers = em.createNamedQuery("findAllCustomersWithName")
.setParameter("custName", "Smith")
.getResultList();
2.2.5.1- Sorgulardaki İsim Parametreleri
Parametre geçiren isimler javax.persistence.Query.setParamater (String
name, Object value) metodu kullanarak sınırlandırılırlar. Aşağıdaki örnekte
findWithName ve setParameter metodu kullanarak parametre geçiliyor.
public List findWithName(String name) {
return em.createQuery(
"SELECT c FROM Customer c WHERE c.name LIKE :custName")
.setParameter("custName", name)
.getResultList();
}
2.2.5.2- Sorgulardaki Durumsal Parametreler
İsim yerine durumsal parametre de kullanılır. Kullanım yapısı (?) den sonra
gelen sayı gelen parametrenin sorgudaki yerini verir.Query.setParameter(integer
position ,Object value) bu metot parametre geçmek için kullanılır.
public List findWithName(String name) {
return em.createQuery(
“SELECT c FROM Customer c WHERE c.name LIKE ?1”)
.setParameter(1, name)
.getResultList();
}
Giriş parametreleri 1. giriş parametrelerinden sıralanmaya başlar.

2.3- Persistence Birimleri
Persistence bolumu varlık yöneticisi örnekleri tarafından yönetilen bütün varlık
sınıflarını tanımlar.Bu Entity grupları tek bir bilgi deposunda bulunan bilgileri temsil
eder.
Persistence bölümleri persistence.xml konfigürasyon dosyası tarafından

tanımlanır.META-INF dizini persistence.xml içeren JAR dosyası ya da dizini,
persistence bölümünün kaynağı olarak adlandırılır.
Persistence bölümünün çalışma alanı persistence bölümünün kaynağı tarafından
belirlenir.Her bir persistence bolumu kendi çalışma alanına özel bir isimle
tanımlanmak zorundadır.
Persistence bölümleri WAR ya da EJB JAR dosyalarını parçası olarak birlikte
kullanılabilir.Ayrıca WAR ya da EAR dosyalarının içine eklenebilecek bir JAR dosyası
olarak da birlikte kullanılabilir.
Eğer persistence bölümünü bir grup olarak bir EJB JAR dosyası içinde
kullanırsanız, persistence.xml EJB JAR in META-INF dizini içine yerleştirilmelidir.
Eğer persistence bölümünü bir grup olarak bir WAR dosyası içinde kullanırsanız,
persistence.xml WAR dosyasının WEB-INF/classes/META-INF dizini içine
yerleştirilmelidir.
Eğer persistence bölümünü WAR ya da EAR dosyası içine dahil edilecek bir
JAR dosyası içinde kullanırsanız, JAR dosyası aşağıdaki bölümlerden birisine
yerleştirilmelidir.
- WAR in WEB-INF/lib dizini
- Bir EAR dosyasının en üst seviyesi
- EAR dosyalarının kütüphane dizini
2.3.1- Persistence.xml Kütüğü
Persistence.xml bir ya da birçok persistence birimi tarafından tanımlanır.
Aşağıdaki örnek bir persistence.xml kütüğüdür.


This unit manages orders and customers.
It does not rely on any vendor-specific features and can
therefore be deployed to any persistence provider.

jdbc/MyOrderDB
MyOrderApp.jar
com.widgets.Order
com.widgets.Customer



Bu dosyanın içinde OrderManagement denilen bir persistence parçası tanımlıdır ve
JTA tarafından kullanılırlar. JAR dosyası ve sınıf elemanları persistence sınıflarını
yönetirler

1 Mayıs 2009 Cuma

Enum

Java'da en cok karsilasilan ve eksikligi hissedilen ozelliklerden birisi C ve C++'ta sikca kullanilan enum operatorudur. Aslinca C tipi enumlar kullanilmasi son derece guvensiz yapilardir. enum sabit degerli bir dizi olusturulur. En cok kullanilan ama kullanilmasi onerilmeyen integer sabitler (C'de oldugu gibi) genellikle java'ya baslayanlarin ilk basvurdugu yontemdir. bu tip enum su nedenlerden oturu sakincalidir.- Typesafe degil, yani kaza ile bir integer bu degerler yerine kullanilabilir. guvensiz kod olusumu- degerlerin basina ek bilgisi eklemek gerekebilir- degerler bilgi verici degil (debug sirasinda ya da log yazilirken sadece rakamlar gorunur.)
public class Almanak {
public static final int MEVSIM_KIS = 0;
public static final int MEVSIM_BAHAR = 1;
public static final int MEVSIM_YAZ = 2;
public static final int MEVSIM_SONBAHAR = 3;
.... }

javada guvenli enum kullanimi icin ciddi tasarim yapmak gerekebiliyordu. Sirf enum siniflari olusturmak icin IDE yazilimlarinda ozel araclar bile kullaniliyor. Normalde guvenli bicimde hakkini vererek gerceklestirmek icin sayfa boyu kod gerektirebilecek oyun kagidi destesi olusturma islemi Java 1.5 typesafe enum, generics ve gelismis for ile asagidaki sekilde kolayca gerceklestirilir. asagida goruldugu gibi sadece enum Tip { maca, sinek, karo, kupa} diyerek dortlu bir kume olusturuluyor. Bu degerler ancak Tip sinifina ait nesnelere atanabilir oldugundan hatali kullanim ihtimali cok dusuktur. Kullanimi da C ve C++'a benzediginden programcilar yabancilik cekmeyecektir. Bu ifadelerin bir switch-case blogunda kullanilmasi da mumkun (bu onceden kodla tasarlanan guvenli enum siniflari icin mumkun degildi)

enum Tip {
maca, sinek, karo, kupa }

enum Deger {
ikili, uclu, dortlu, besli, altili, yedili,
sekizli, dokuzlu, onlu, vale, kiz, papaz, as
}
// desteye kartlari ekle List deste = new ArrayList();
for (Tip tip : Tip.VALUES)
for (Deger deger : Deger.VALUES)
deste.add(new Kart(Tip, Deger));
// desteyi karistir
Collections.shuffle(deste);
Baska bir ornek, bu defa enum sinif oalrak ifade ediliyor. icindeki bilesenlere deger atanabiliyor. Goruldugu gibi sebze enum sinifinda hem sebzeler, hem sebzelerin fiyatlari yuklenebiliyor. Ayrica bu sinifi kullanan yazilimin ikinci parcasinda enum sinifinin switch blogunda nasil kullanilacagi gosteriliyor.

public enum Sebze {
domates(500), salatalik(550), biber(1000), patlican(700);
Sebze( int fiyat) {
this.fiyat = fiyat;
}
private final int fiyat;
public int fiyat () { return fiyat;
}
}
public class SebzeTest { public static void main(String[] args) {
for (Sebze s : Sebze.VALUES)
System.out.println(s + ": \t"
+ s.value() + "bin TL \t" + renk
(s));
}
private enum SebzeRengi {
kirmizi, yesil, mor
}
private static SebzeRengi renk(Sebze s) {
switch (s) {
case domates:
return SebzeRengi.kirmizi;
case patlican:
return SebzeRengi.mor;
case salatalik:
case biber:
return SebzeRengi.yesil;
default:
throw new AssertionError("Bilinmeyen sebze: " + s); }
}
}

26 Nisan 2009 Pazar

Visa FacadeBean

@Stateless
public class VisaRequestFacadeBean implements VisaRequestFacadeRemote, VisaRequestFacadeLocal {
@PersistenceContext EntityManager em;
public void createVisaRequest(VisaRequests visaRequest) {
em.persist(visaRequest);
}


public List getVisaRequestsList() {
return em.createQuery("select object(o) from VisaRequests as o").getResultList();
}

public void createVisa(Visas visa) {
em.persist(visa);
}

public VisaRequests getOriginalRequest(String requestUUID) {
return (VisaRequests) em.createQuery("SELECT v FROM VisaRequests v WHERE v.uuid = :uuid").setParameter
("uuid", requestUUID).getSingleResult();
}

public void setVisa(String requestUUID, Visas visa) throws VisaExceptions { VisaRequests request = (VisaRequests)em.createQuery("SELECT v FROM VisaRequests v WHERE v.uuid = :uuid").setParameter
("uuid", requestUUID).getSingleResult();
request.setVisa(visa);
em.merge(request);
}

public void addDocumentToVisaRequest(Documents document ){
em.persist(document);
}

public PaymConfirmations getVisaPaymentConfirmation(String requestUUID){
return (PaymConfirmations) em.createQuery("SELECT v FROM VisaRequests v WHERE v.uuid = :uuid").setParameter
("uuid", requestUUID).getSingleResult();
}

public boolean isPaymentConfirmed(String requestUUID){

VisaRequests request = (VisaRequests)em.createQuery("SELECT v FROM VisaRequests v WHERE v.uuid = :uuid").setParameter ("uuid", requestUUID).getSingleResult();
// return reqeuest.getPaymentConfirmation() != null; return request.getPaymConfirmationsCollection() !=null;
}

public boolean setPaymentConfirmed(String requestUUID, PaymConfirmations paymantConfirmation){
VisaRequests request = (VisaRequests)em.createQuery("SELECT v FROM VisaRequests v WHERE v.uuid = :uuid").setParameter("uuid", requestUUID).getSingleResult();
request.setFkPaymentConfirmationUid(paymantConfirmation);
return true;
}
// public List lookupRequests(String requestUUID, IdentificationTemplate){}
}

1 Nisan 2009 Çarşamba

Login1




31 Mart 2009 Salı

JAZN oracle security

Bu yazimizda oracle`in JAZN security`ini kullanarak bi EE uygulamalrinda admin panelinde nasil kullanacagizi gorecez. Oncelikle bize gerkeli olan class`lari, hangi classlar bizim isimize yarayacak onlara belirleyelim. Bunun icin bizim birtane User ve Role class olmalidir.

public class Role {
protected String name;
public String getName() throws AppSecurityException{
return this.name;
}
public void setName(String name)throws AppSecurityException{
this.name = name;
}
}

public class User {
protected String name;
protected boolean value;

public String getName()throws AppSecurityException{
return this.name;
}
public void setName(String name){
this.name = name;
}
public boolean isLocked() throws AppSecurityException{
return this.value;
}
public void setLocked(boolean value) throws AppSecurityException{
this.value = value;
}
}

Yukarida goruldugu gibi burada bizim icin gerekli olan degiskenler mevcut. Simdi ise sira bir tane abstract class oluturmak olacak, burada interface`de olabilir. ama biz abstract class yaptik. Cunku metodumuzun bitanesinin icini doldurmak istiyoruz.

public abstract class SecurityManager {
public static SecurityManager getInstance(String instanceName) throws AppSecurityException {
if(("jazn").equalsIgnoreCase(instanceName)){
return new SecurityManagerJAZN();
} else{
throw new AppSecurityException("NOT FOUND");
}
}
public abstract User createUser(String username, String password);
public abstract List getUsers() throws AppSecurityException;
public abstract User getUser(String username) throws AppSecurityException;
public abstract void dropUser(User user) throws AppSecurityException;
public abstract void dropUser(String username) throws AppSecurityException;
public abstract Role createRole(String roleName) throws AppSecurityException;
public abstract void dropRole(Role role) throws AppSecurityException;
public abstract List getRoles() throws AppSecurityException;
public abstract Role getRole(String roleName) throws AppSecurityException;
public abstract List getRoles(User user) throws AppSecurityException;
public abstract List getRoles(Role role) throws AppSecurityException;
public abstract void grantRole(User user , Role role)throws AppSecurityException;
public abstract void grantRole(Role role , Role grantee )throws AppSecurityException;
public abstract void revokeRole(User user, Role role) throws AppSecurityException;
}
Evet birtanede SecurityManager abstract clasimiz oldu. Simdi sira geldi bunlarin icini doldurmaya.
Bunun icin birtane SecurtityManagerJAZN classimizi olusturalim

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import oracle.security.jazn.JAZNContext;
import oracle.security.jazn.JAZNException;
import oracle.security.jazn.realm.Realm;
import oracle.security.jazn.realm.RealmManager;
import oracle.security.jazn.realm.RealmRole;
import oracle.security.jazn.realm.RealmUser;
import oracle.security.jazn.realm.RoleManager;
import oracle.security.jazn.realm.UserManager;
import org.accr.model.exception.AppSecurityException;
import org.accr.model.security.Role;
import org.accr.model.security.SecurityManager;
import org.accr.model.security.User;

public class SecurityManagerJAZN extends SecurityManager{

protected String realmName = "jazn.com";

public User createUser(String username, String password) throws AppSecurityException { try{
RealmManager reamMgr = JAZNContext.getRealmManager();
Realm realm = reamMgr.getRealm(realmName);
UserManager userMgr = realm.getUserManager();
RealmUser realmUser = userMgr.createUser(username,password);
User user = new User();
user.setName(realmUser.getName());
return user;
}catch(JAZNException e){
throw new AppSecurityException(e);
}
}

public List getUsers() throws AppSecurityException {
try{
RealmManager reamMgr = JAZNContext.getRealmManager();
Realm realm = reamMgr.getRealm(realmName);
UserManager userMgr = realm.getUserManager();
Set users = userMgr.getUsers();
Iterator iter = users.iterator();
ArrayList userList = new ArrayList();
while(iter.hasNext()){
RealmUser realmUser = (RealmUser)iter.next();
User user = new User();
user.setName(realmUser.getName());
userList.add(user);
}
return userList;
}catch(JAZNException e){
throw new AppSecurityException(e);
}
}

public User getUser(String username) throws AppSecurityException {
try{
RealmManager reamMgr = JAZNContext.getRealmManager();
Realm realm = reamMgr.getRealm(realmName);
UserManager userMgr = realm.getUserManager();
RealmUser realmUser = userMgr.getUser(username);
User user = new User();
user.setName(realmUser.getName());
return user;
}catch(JAZNException e){
throw new AppSecurityException(e);
}
}

public void dropUser(User user) throws AppSecurityException {
String username = user.getName();
this.dropUser(username);
}

public void dropUser(String username) throws AppSecurityException {
try{
RealmManager reamMgr = JAZNContext.getRealmManager();
Realm realm = reamMgr.getRealm(realmName);
UserManager userMgr = realm.getUserManager();
userMgr.dropUser(username);
}catch(JAZNException e){
throw new AppSecurityException(e);
}
}

public Role createRole(String roleName) throws AppSecurityException{
try{
RealmManager reamMgr = JAZNContext.getRealmManager();
Realm realm = reamMgr.getRealm(realmName);
RoleManager realmMgr = realm.getRoleManager();
RealmRole realmRole = realmMgr.createRole(roleName);
Role role = new Role();
role.setName(realmRole.getName());
return role;
}catch(JAZNException e){
throw new AppSecurityException(e);
}
}

public void dropRole(Role role) throws AppSecurityException {
String roleName = role.getName();
this.dropUser(roleName);
}

public List getRoles() throws AppSecurityException {
try{
RealmManager reamMgr = JAZNContext.getRealmManager();
Realm realm = reamMgr.getRealm(realmName);
RoleManager roleMgr = realm.getRoleManager();
Set rols = roleMgr.getRoles();
Iterator iter = rols.iterator();
ArrayList roleList = new ArrayList();
while(iter.hasNext()){
RealmRole realmRole = (RealmRole)iter.next();
Role role = new Role();
role.setName(realmRole.getName());
roleList.add(role);
}
return roleList;
}catch(JAZNException e){
throw new AppSecurityException(e);
}
}

public Role getRole(String roleName) throws AppSecurityException {
try{
RealmManager reamMgr = JAZNContext.getRealmManager();
Realm realm = reamMgr.getRealm(realmName);
RoleManager roleMgr = realm.getRoleManager();
RealmRole realmRole = roleMgr.getRole(roleName);
Role role = new Role();
role.setName(realmRole.getName());
return role;
}catch(JAZNException e){
throw new AppSecurityException(e);
}
}

public void grantRole(User user, Role role) throws AppSecurityException {
try{
RealmManager realmMgr = JAZNContext.getRealmManager();
Realm realm = realmMgr.getRealm(realmName);
UserManager userMgr = realm.getUserManager();
String userName = user.getName();
RealmUser realmUser = userMgr.getUser(userName);
RoleManager roleMgr = realm.getRoleManager();
RealmRole realmRole = roleMgr.getRole(role.getName());
roleMgr.grantRole(realmUser,realmRole);
}catch(JAZNException e){
throw new AppSecurityException(e);
}
}

public void grantRole(Role role, Role grantee) throws AppSecurityException {
try{
RealmManager realmMgr = JAZNContext.getRealmManager();
Realm realm = realmMgr.getRealm(realmName);
String roleName = role.getName();
RoleManager roleMgr = realm.getRoleManager();
RealmRole realmRole = roleMgr.getRole(roleName);
RealmRole realmGrantee = roleMgr.getRole(role.getName());
roleMgr.grantRole(realmRole, realmGrantee);
}catch(JAZNException e){
throw new AppSecurityException(e);
}
}

public void revokeRole(User user, Role role) throws AppSecurityException {
try{
RealmManager realmMgr = JAZNContext.getRealmManager();
Realm realm = realmMgr.getRealm(realmName);
UserManager userMgr = realm.getUserManager();
String userName = user.getName();
RealmUser realmUser = userMgr.getUser(userName);
RoleManager roleMgr = realm.getRoleManager();
RealmRole realmRole = roleMgr.getRole(role.getName());
roleMgr.revokeRole(realmUser, realmRole);
}catch(JAZNException e){
throw new AppSecurityException(e);
}
}

public List getRoles(User user) throws AppSecurityException {
try{
RealmManager reamMgr = JAZNContext.getRealmManager();
Realm realm = reamMgr.getRealm(realmName);
RoleManager roleMgr = realm.getRoleManager();
UserManager userMgr = realm.getUserManager();
String userName = user.getName();
RealmUser realmUser = userMgr.getUser(userName);
Set rols = roleMgr.getGrantedRoles
(realmUser,true);
Iterator iter = rols.iterator();
ArrayList roleList = new ArrayList();
while(iter.hasNext()){
Role role = new Role();
role.setName(iter.next().getName());
roleList.add(role);
} return roleList;
}catch(JAZNException e){
throw new AppSecurityException(e);
}
}

public List getRoles(Role role) throws AppSecurityException { try{
RealmManager reamMgr = JAZNContext.getRealmManager();
Realm realm = reamMgr.getRealm(realmName);
RoleManager roleMgr = realm.getRoleManager();
String roleName = role.getName();
RealmRole realmRole = roleMgr.getRole(roleName);
Set rols = roleMgr.getGrantedRoles(realmRole, true);
Iterator iter = rols.iterator();
ArrayList roleList = new ArrayList();
while(iter.hasNext()){
Role role1 = new Role();
role.setName(iter.next().getName());
roleList.add(role1);
}
return roleList;
}catch(JAZNException e){
throw new AppSecurityException(e);
}
}
}

30 Mart 2009 Pazartesi

Karisik Resimler



Bende ogrenciyim ama evimiz hic bu hale gelmemisti :), herkes battaniyesini evinden getirmis heralde









Dogru yol :), amca ters :)


29 Mart 2009 Pazar

(JAAS) ve EJB Güvenliği

JAAS java uygulamaları için kimlik doğrulama ve yetkilendirme işlemlerini portatif bir şekilde yapılmasını sağlayan bir arayüzdür. JAAS'ı kullanarak kendiniz sisteme giriş yapmayı ve yetkilendirmeyi sağlayan mödüler API'ler yazabilirsiniz.JAAS'ı herhangi bir güvenlik sisteminde kullanabilirsiniz. Örneğin; bir uygulama sunucusu kimlik doğrulamayı bir dosyadan okuyarak yapıyor olabilir yada bir veritabanından sorgulatarak ya da bir LDAP sunucusuna bağlanarak yapıyor olabilir. JAAS ile bu ortamlara ayak uydurmak hiç dert değil. Çünkü JAAS interface'lerden oluşur ve siz de bu interface'leri implemente edersiniz. Böylece kimse kimseye darılmaz.JAAS EJB güvenliğinde sıklıkla kullanılır. Sun, JAAS'ı EJB güvenliğinde standard olarak kullanmaktadır.Genelde JAAS modüllerinin kullanımı ile ilgili iki tip senaryo vardır:
Bir masaüstü uygulamanız vardır ve bu uygulamanız uzak bir uygulama sunucusuna bağlanıp sisteme giriş yapacaktır. Sisteme giriş sağlandıktan sonra da kullanıcının yetkileri oluşturulup bu yetkilerine göre sistemde hangi modüllere erişip hangi modüllere erişemeyeceği belirlenecektir. Bunun için masaüstü uygulamanız JAAS ile kullanıcının giriş bilgilerini uygulama sunucusuna iletir. Uygulama sunucusu da bu bilgileri kullanarak sisteme girişi gerçekleştirip kullanıcının rollerini oluşturur. Bundan sonraki EJB metodlarının çağırılmasında kullanıcının rol bilgilerine bakılır. Eğer yetkisi varsa izin verilir yoksa izin verilmez.
Bir web tarayıcı aracılığı ile sisteme giriş yapabilirsiniz. Burada da kullanıcının giriş bilgileri JSP/servlet'e aktarılır. JSP/Servlet'de bu bilgileri kullanarak sisteme girişi gerçekleştirir. Tarayıcı giriş bilgilerini aşağıdaki yöntemleri kullanarak aktarır:
Basic authentication
Form-based authentication
Digest authentication
Certificate authenticationMasaüstü uygulamaları gibi web uygulamasında da sisteme giriş gerçekleştiğinde, istemci EJB metodlarını kullancının yetkileri izin verdiği ölçüde çağırır.JAAS'ın çalışma mantığına bakacak olursak aşağıdaki maddeler çıkabilir:
İstemci yeni bir LoginContext nesnesi oluşturur. Bu sınıf JAAS tarafından sunulmuştur ve kimlik doğrulama (authentciation) sürecinden sorumludur.
LoginContext nesnesi bir Configuration nesnesi alır. Bu nesnede kimlik doğrulama işleminin hangi LoginModule'ler ile yapılacağı bildirilir. Örneğin bir sistem sadece kullanıcı adı ve şifre doğrulaması istersen başka bir sistem hem kullanıcı adı-şifre hem de sertifika bazlı doğrulama isteyebilir.
LoginContext Configuration nesnesine kimlik doğrulama mekanizmalarının neler olduğunu sorar.
Configuration nesnesi kimlik doğrulama mekanizmalarından oluşan mekanizmalardan oluşan bir liste döndürür. Bu mekanizmaların her birine login module denmektedir. Login Module JAAS'ın sunduğu bir interface'dir. LoginModule kimlik doğrulama işleminin yapıldığı birimlerdir.
LoginContext LoginModule sınıflarından birer nesne oluşturur.
LoginContext oluşturulan LoginModule nesnelerini ilklendirir.
İstemci kodu LoginContext nesnesi üzerinden login() metodunu çağırır.
LoginContext login işlemlerini LoginModule nesnelerine devreder. Çünkü kimlik doğrulama işlemlerinin nasıl yapılacağını bu modüller bilmektedir.
Sizin tarafınızdan yazılmış LoginModule nesneleri kimlik doğrulama işlemini gerçekleştirir.
İşlem sonucu oluşturulan bilgiler Subject sınıfından oluşturulmuş bir nesnenin içinde saklanır. Bu nesneyi güvenli işlemler gerçekleştirmek için kullanırsınız.
Bundan sonra istemci kodu EJB metodlarını çağırır ve sistem giriş bilgisi bu metod çağırımlarında otomatik olarak iletilir. Böylece uygulama sunucusu bu bilgileri kullanarak kimlik doğrulama ve yetkilendirme işlemlerini yapar.Aşağıda yukarıdaki yapının resim olara çizilmiş halini görebilirsiniz:Bu yazıda JAAS yüzeysel olarak incelenmiştir. Detaylı bilgi için lütfen bkz. JAAS Reference GuideJAAS Java SE ile birlikte gelmektedir. Böylelikle ayrı bir jar indirmenize gerek yoktur.Bir sonraki yazıda JAAS kullanarak bir JBOSS uygulama sunucusundaki EJB'lere güvenli erişmeyi sağlayan bir örnek anlatılacaktır.Kaynak: Mastering Enterprise Java Beans 3.0

29 Ocak 2009 Perşembe

EJB

EJB belirtimine göre üç temel bileşen çeşidi bulunmaktadır. Bunlar:

1- Entity Bean
2- Session Bean
3- Message-Driven Bean

Yukarıdaki ilk iki bileşen ilk kez EJB1.0 ve EJB 1.1 belirtimlerinde tanımlanmıştır. Bu yazıda verilecek bilgiler EJB1.1 belirtiminde tanımlanmış özellikleri kapsamaktadır. Message-Driven Bean ise EJB 2.0 belirtimiyle birlikte ortaya çıkmıştır. Message-Driven Bean ve EJB 2.0 ile gelen özelliklerden sonraki yazılarda bahsedilecektir.

Burada tanımlanan bileşen çeşitlerini detaylandırmadan önce bileşenlerin genel olarak sahip oldukları özellikleri belirtmekte fayda vardır.

EJB’nin İskeleti

EJB’nin öncelikle bilinmesi gereken özelliği dağıtık nesne teknolojilerini kullanmasıdır ve şu anda J2EE platformunun standart olarak kullandığı dağıtık nesne protokolü IIOP’dur. Ancak herhangi bir J2EE platformu (uygulama sunucusu da denilebilir) satıcısı kendi tescilli protokolünü bunun yanında kullanabilir. Bilindiği gibi dağıtık nesneler istemci tarafındaki bir vekil (stub) vasıtasıyla sunucu tarafındaki bir nesneye ulaşır. Bu mekanizma ile alakalı ayrıntılı bilgiyi bir önceki yazıda (EJB Nedir? -2) bulabilirsiniz. Tipik bir EJB bileşeni en azından şu üç sınıfı içerir:

1- Home Interface
2- Remote Interface
3- Bean Class

1) Home Interface

Bu “interface” bir EJB’nin yaşamsal döngüsünü belirleyen bir arayüzdür. Burada iki çeşit metod tanımlanabilir:

-create (yaratma) metodları
-finder (arama) metodları

Şunu baştan söylemek gerekir ki bir istemci bir bean'e her zaman uzaktan (remote) erişir. Bu kritere dayanarak home interface'i en basit ifadeyle şöyle tanımlayabiliriz. Sunucu tarafında varolan bir bean sınıfına erişimi sağlayan remote interface'i yaratmaya ya da bulmaya yarar. Aslında karmaşık gibi görünen bu ifade home interface’in görevlerinin büyük bir bölümünü oluşturur. Bu metodların özellikleri bileşenden bileşene (entity, stateful session, stateless session) değişir. Örneğin finder metodlar session bean’lerde bulunmazlar fakat entity bean'lerde en az bir tane (findByPrimaryKey) bulunmak zorundadır.

2) Remote Interface

Bu arayüz bean sınıfında tanımlanan tüm iş mantığı metodlarının aynısını içinde barındırır. Bu sayede istemci bean sınıfına direk olarak ulaşmadan bu arayüz vasıtasıyla bean sınıfının metodlarını çağırabilir. Buradan da anlaşılabildiği gibi bu arayüz bir kontrol mekanizması (controller) sağlar. Böylece “container” tarafından oluşturulan bu arayüzün implementasyon sınıfında çeşitli servisler sağlanabilir. Bu servisler böylece bean geliştiriciden bağımsız olarak gerçekleştirilmiş olur.

3) Bean Class

İş mantığının asıl gömüldüğü sınıftır. Bu sınıf sunucu tarafında bulunur ve sadece remote interface aracılığıyla erişilebilir.

Yukarıda bir EJB bileşenini oluşturan en temel üç parçayı gösterdik. Bunun yanında sadece entity bean’lerde kullanılan primary key sınıfı bulunur. Şimdi EJB bileşen çeşitlerini incelemeye başlayalım.

Entity Bean

Entity Bean EJB 1.0 belirtiminde opsiyonel olarak tanıtılmıştır ancak verinin objeleştirilmesinde gösterdiği başarı sayesinde EJB dünyasında yaygın bir şekilde kullanılmaya başlanmıştır. Bu yüzden EJB 1.1’de EJB Container’ların bu bileşen çeşidini desteklemeleri zorunlu hale getirilmiştir.

Entity bean herhangi bir veri kaynağındaki veriyi temsil eder. Örneğin ilişkisel bir veritabanında bulunan bir tablonun bir satırı bir entity bean instance’ına denk gelir. Bu bize ne avantaj sağlar? Sağladığı en büyük avantaj verinin objeleştirilmesidir. Bu sayede gerçekleştireceğimiz uygulamalarda veri kaynağı yerine nesnelerle uğraşırız. Ayrıca yazdığımız uygulamalar veri kaynağından bağımsız olur. Çünkü verinin veri kaynağından alınma işlemi bean sınıfından bağımsızdır ve container tarafından gerçekleştirilir. Biz bean uygulama geliştiricisiolarak uygulamalarımızı veri kaynağıyla alakalı sorunlardan bağımsız bir şekilde gerçekleştiririz.

Tanımlanmış olan iki tip entity bean vardır: CMP (Container-Managed Persistence) Entity Bean ve BMP (Bean-Managed Persistence) Entity Bean.

CMP Entity Bean

Bu bileşen çeşidinde veri kaynağı ile senkronizasyon işlemi tamamen container’a bırakılmıştır. Yani siz entity bean’i yazarsınız. Fakat bu bean’in veri kaynağından veriyi alma ve veri kaynağına veriyi yazma işlemleri container tarafından gerçekleştirir. Tabii ki bu geliştirici için idealdir fakat container üreticisi çok gelişmiş bir mapping özelliğini gerçekleştirmek zorundadır. Burada container üreticilerinin arasındaki performans farkları ortaya çıkar. Aslında J2EE sertifikalı tüm uygulama sunucuları bu işlemi gerçekleştirir fakat performans farkı kimin bu işi daha iyi yaptığını belirler.

BMP Entity Bean

Buradaki mapping işlemi tamamen geliştirici üzerine yüklenmiştir. Bazı durumlarda uygulamanın performansının artması için bu kaçınılmazdır. Bazen container’ın başedemeyeceği kadar büyük mapping sorunları da çıkabilir. Ayrıca sizin etkileşimde bulunmak istediğiniz veri kaynağını container satıcısı desteklemeyebilir. Bu sorunlar karşısında geliştirici kılıcını kuşanır ve senkronizasyon işlemini üstlenir. BMP’nin dezavantajlarından biri ise bileşene veri senkronizasyon kodu gömüldüğünden veri kaynağına bağımlı hale gelmesidir. Fakat bu da değişik mekanizmalarla önlenebilir. Bunlardan biri DAO (Data Access Object) pattern kullanımıdır.

Session Bean

Uygulamadaki iş akışını kontrol eden bileşenlerdir. Entity bean’in veriyi objeleştirdiğini yukarıda belirtmiştik. İşte bir uygulamanın ortaya çıkması için bu verinin bir şekilde işlenmesi gerekir. Çünkü bir uygulamanın çalışması demek sistemde bulunan verilerin anlamlı şekilde değişmesi demektir. Bu görevi session bean gerçekleştirir. Session bean, entity bean’leri kullanarak ve işleyerek, örneğin, bir ticari işletmenin iş akış süreçlerini gerçekleştirebilir. Bir diğer değişle ünlü iş mantığı (business logic) çoğunlukla session bean’ler tarafından gerçekleştirilir. Session bean de kendi içinde iki parçaya ayrılır.

- Stateful Session Bean (SFSB)
- Stateless Session Bean (SLSB)

Stateful Session Bean

Bu session bean çeşidi sunucu tarafındaki bir bean’nin istemci tarafındaki uzantısı olarak düşünülebilir. Sadece bir istemcinin isteklerini gerçekleştirir. SFSB’nin özelliği bean instance'ın yaşam süresi boyunca bir durum bilgisi (state) tutmasıdır. Kısaca bean üzerinde çağrılan farklı metodlar birbirlerinden haberdar olabilirler. Bu state bean sınıfının değişkenlerinde tutulur. Bunu basit bir örnekle açıklayalım. Örneğin bir istemci bir e-ticaret sitesine girsin. Bu ziyaretçinin bu siteden istediği malları alış-veriş sepetine attığını düşünelim. Bu istemci siteden malları seçtikçe bu alışveriş sepeti dolmaya başlayacaktır. İşte bunun anlamı bu istemci için sunucuda tutulan bir SFSB’nin bu malları bellekte tutması demektir. Eğer istemci bu malları almaktan vazgeçerse ya da satın alma işlemini başlatmazsa bu alış-veriş sepetindeki mallar istemci sunucuyla ilişkiyi kestiğinde kaybolur. (Aslında çoğu e-ticaret sitesi bu malları bir veritabanına yazar ve aynı istemcinin bir sonraki ziyaretinde karşısına çıkartabilir. Fakat biz burada bunların kaydedilmediğini varsayıyoruz). Bunun anlamı sunucudaki SFSB’nin yok edilmesidir.

SFSB bir diğer ifadeyle iş akışlarındaki senaryoların gerçekleştirilmesi anlamına da gelir. Bu senaryoları yazılımcı SFSB olarak tasarlar ve entity bean’leri bu senaryolara göre işleyerek işletmenin ihtiyaçlarını karşılar.

Stateless Session Bean

Stateless session bean küçük iş parçacıklarıdır. SFSB’den farkı hiçbir istemciye bağımlı olmayışıdır. İstemcilerle alakalı bilgi tutmaz. Fonksiyonel dillerde kullanılan RPC (Remote Procedure Call) ile eşdeğerdedir. Çünkü istemci metod çağrımını yapar ve sonucunu alır. Sistemde bu işlemle alakalı hiçbir durum bilgisi tutulmaz.

Performans bakımından en verimli olan bean'dir. Tüm ihtiyaç duyduğu bilgiyi parametre olarak alır ya da bir veri kaynağından elde eder. SLSB’lere en güzel örneklerden biri onaylama işlemleridir. Mesela bir transaction içerisinde bir öğrencinin bir dersten yeterli notu alıp almadığını kontrol etmek istersek bunu bu tip işlerin toplandığı bir stateless session bean içerisindeki bir metod vasıtasıyla gerçekleştirebiliriz. Bu metod çağrımı sonucunda bize sadece doğru ya da yanlış diye bir yanıt döndürülür.

Şimdi burada önemli bir noktaya değinelim. Yukarıdaki örnekte neden entity bean kullanmadık? Aslında ilk bakışta entity bean kullanmak mantıklı gelebilir. Ancak performans açısından bakıldığında SLSB kullanımı ön plana çıkar. Çünkü entity bean'in yaratılması sisteme SLSB’nin yaratılmasından daha fazla yük getirir. İkincisi ise entity bean yaratılırken sadece gerekli olan değişkenin değil tüm değişkenlerin veritabanıyla senkronizasyonu sağlanması gerekir. Fakat SLSB kullanıldığında yapılan tek şey yaratılan stateless bean'e öğrencinin numarasının verilmesi ve bu numara kullanılarak veritabanından istenen bilginin elde edildikten sonra karşılaştırma işleminin sonucunun döndürülmesidir. Bu gibi performans arttırımı sağlayan yaklaşımlarda her zaman SLSB kullanılmalıdır.

Kaynak
http://www.teknoturk.org/docking/yazilar/tt000093-yazi.htm

26 Ocak 2009 Pazartesi

Trigger kullanimi

Trigger - her hangi bir DML ve ya DDL emrleri calistiqinda calisan program kodudur. Bunu asagidaki basit bir ornekle gosterebiliriz..
Mesela bir table-imiz var, o table-a insert, update, delete eden user-lerin istifadeci adlarini, host-unu ve bu emri icra etdiyi tarihi control edib diger bir "log" table-ina yazmamiz lazim.

Boyle bir orneye bakalim

CREATE TABLE tbl_trigger_test (ID NUMBER, adi VARCHAR2(20))
/
CREATE TABLE tbl_log_trigger_test (username VARCHAR2(20), tarih DATE, host VARCHAR2(20), emeliyyat VARCHAR2(20))
/
INSERT INTO tbl_trigger_test
VALUES (1, 'Ertugrul')
/
COMMIT
/
CREATE OR REPLACE TRIGGER trg_trigger_test
BEFORE INSERT OR UPDATE OR DELETE
ON tbl_trigger_test
DECLARE
v_islem VARCHAR2 (20);
BEGIN
IF INSERTING
THEN
v_islem := 'INSERT';
ELSIF UPDATING
THEN
v_islem := 'UPDATE';
ELSIF DELETING
THEN
v_islem := 'DELETE';
END IF;

INSERT INTO tbl_log_trigger_test
VALUES (USER, SYSDATE, SYS_CONTEXT ('USERENV', 'HOST),
v_islem);
END;
Simdi, her defa tbl_trigger_test tablomuza INSERT, UPDATE, DELETE emrlerini uyqulasak, o zaman tbl_log_trigger_test tablomuz bir row eklenecekdir

SQL>SELECT * FROM tbl_log_trigger_test;
no rows selected

Log tablosunun ici bos. Simdi esas tabloya bazi satirlar ilave edib silelim, bakalim log-a alinicakmi?
SQL> insert into tbl_trigger_test values(2,'Asalan');

1 row created.

SQL> update tbl_trigger_test set id=0 where id=1;

1 row updated.

SQL> delete from tbl_trigger_test where id=0;

1 row deleted.

SQL>select * from tbl_log_trigger_test;
Ertugrul 24-JAN-2009 15:13:09 localhost INSERT
Ertugrul 24-JAN-2009 15:13:25 localhost UPDATE
Ertugrul 24-JAN-2009 15:13:49 localhost DELETE

10 Aralık 2008 Çarşamba

Exception Handling (Hata Yakalama)

Her programlama dilinde oldugu gibi Oracle ‘ın prosedürel veritabanı programlama dili olan PL/SQL de de gerek derleme sırasında(compile time), gerekse programın çalışması esnasında(run time) hata durumu ortaya çıkabilir.Bu yazıda bunların tespit edip yakalama ve program akışını buna göre düzenlemeye yönelik kısa bilgiler bulacaksınız.

PL/SQL de işlemi gercekleştirecek kod parcacıkları fonksiyon, procedür ya da script seklinde bir kod blogu ile olabilir.Hepsinin ortak yanı :


declare
–gerekirse değişken tanımları
begin
…………
………….
……………
……………….
end;

şeklinde bir bloktan oluşmalarıdır.NOT : Fonksiyon ve prosedür için örnekler şu şeklide verilebilir :


Fonksiyon örneği :
function fonksiyonXXX(param1 varchar2,param2 number….) return aDataType is
–gerekirse değişken tanımları
begin
…………
………….
……………
……………….
return aDataType;
end fonksiyonXXX;

Procedür örneği :
procedure procedurXXX (param1 varchar2,param2 number….) is
–gerekirse değişken tanımları
begin
…………
………….
……………
……………….
end prosedurXXX;

Türü ne olursa olsun hata yönetimi yapmak, hatayı yakalamak için her begin-end; bloğu arasında bu blokta olusacak hata için “exception” anahtar kelimesi kullanılmalıdır.

declare
begin
….
…..
….
…
exception
………………
end;

“exception” kısmında “end;” sonuna kadar olan kısımda, alınan birden fazla hatayı yakalamak mümkün.Bunun için “when” anahtar kelimesini kullanılır.

begin
……..
……….
………
exception
when exception1 then
———gerekli kodlar
——————–
when exception2 then
———gerekli kodlar
————–
when others then
————
.
.
end;

“exception1, exception2, …exceptionN” önceden tanımlı bir hata olabileceği gibi ,tanımsız olan herhangibir hata ya da kullanıcının tanımladıgı bir hata da olabilir.Önceden tanımlı hatalara örnek olarak

no_data_found
to_many_rows
zero_divide
…..
verilebilir.Bazı önceden tanımlı hatalar ve kodları aşağıda verilmiştir.


Exception Oracle Error SQLCODE Value
ACCESS_INTO_NULL ORA-06530 -6530
CASE_NOT_FOUND ORA-06592 -6592
COLLECTION_IS_NULL ORA-06531 -6531
CURSOR_ALREADY_OPEN ORA-06511 -6511
DUP_VAL_ON_INDEX ORA-00001 -1
INVALID_CURSOR ORA-01001 -1001
INVALID_NUMBER ORA-01722 -1722
LOGIN_DENIED ORA-01017 -1017
NO_DATA_FOUND ORA-01403 +100
NOT_LOGGED_ON ORA-01012 -1012
PROGRAM_ERROR ORA-06501 -6501
ROWTYPE_MISMATCH …………………….. ORA-06504 ……………………. -6504 …………………

Önceden tanımlı hata kodları ile tanımı olmayan diger hatalarda muhakkak bir hata kodu(ORA-xyzwt) bulunmaktadır.Belirli bir hatayı değilde alınan herhangibir ya da belirtilmeyen başka hataları yakalamak için “when” den sonra “others” kullanılır.

NOT : Oracle , hata oluştugu anda bu hataya ait hata kodunu “sqlcode” değişkenine, hata acıklamasını da “sqlerrm” değişkenine otomatik olarak atar.Bunlar gerekirse okunarak kullanılabilir.Kullanıcı tanımlı hatalar için de öncelikte hata değişkeni tanımı yapılmalıdır.Bunun herhangibir veri tipi tanımlamadan farkı yoktur.

declare
something_wrong exception;
declare
if(…) then
raise someting_wrong;
…………….
………
exception
when something_wrong then
–gerekli işlemler…
when others then
–gerekli işlemler….
end;

“exception” bloğuna düşen hatada bir takım işlemler yapılabileceği gibi bu PL/SQL kodunu çağıran yere de bir hata fırlatmak isteyebiliriz.(throw exception).Bunun içinde “raise _applicaion_error(errorID, errorDesc)” kullanılır.“errorID” ve “errorDesc” alanlarını kullanıcı belirler.”errorID” [-20000,-20999] arasında bir değer olmalıdır.”errorDesc” alanıda en fazla 2000 karakterlik “varchar2” veri tipinde açıklama yazılabilir.

Örneğin bir prosedürümüz olsun ve bu prosedür basitçe gönderilen parametrenin 1000’den büyük olup olmadıgını kontrol etsin.Büyük ise yukarı hata versin.

procedure prc_checkValue(p_vlaue number) is
begin
if(p_value > 1000) then
raise_application_error(-20010,’Value is too large);
end;

Bunu yapmanın bir başka yoluda bir hata tanımlayıp bu hatayı “raise etmek :

procedure prc_checkValue(p_vlaue number) is
too_large exception;
begin
if(p_value > 1000) then
raise too_large;
exception
when too_large then
raise_application_error(-20010,’Value is too large);
end;

5 Aralık 2008 Cuma

Kalitim (Inheritance)

Kalıtım konusu nesneye yönelik programlamanın (object oriented programming) en önemli kavramlarından bir tanesidir. Kalıtım kavramı, kısaca bir sınıftan diğer bir sınıfın türemesidir. Yeni türeyen sınıf, türetilen sınıfın global alanlarına ve yordamlarına (statik veya değil) otomatik olarak sahip olur (private olanlar hariç). ()
Unutulmaması gereken unsur, yeni türeyen sınıf, türetilen sınıfın private global alanlarına ve yordamlarına (statik veya değil) otomatik olarak sahip olamaz. Ayrıca yeni türeyen sınıf eğer türetilen sınıf ile ayrı paketlerde ise yeni türeyen sınıf, türetilen sınıfın sadece public ve protected erişim belirleyicisine sahip olan global alanlarına (statik veya değil) ve yordamlarına (statik veya değil) otomatik olarak sahip olur. ()
class Kedi {

//..

}
class Kaplan extends Kedi {

//..

}

Kedi sınıfından türeyen Kaplan sınıfı… İki sınıf arasındaki ilişkiyi şöyle tarif edebiliriz, her Kaplan bir Kedi dir. Yani her kaplan kedisel özellikler taşıyacaktır ama bu özelliklerin üzerine kendisine bir şeyler eklemiştir. ()
Yazılış ifadesi olarak, türeyen sınıf isminin yanına extends ifadesini koyarak, hemen sonrasında kendisinden türetilme yapılan sınıfın kendisini yerleştiririz
Bu konuyu daha iyi bir sekilde pekistirmemiz icin hemen bi ornek yapalim mi :)...

public class Bicycle{
// Bu arada bi hatilatma daha bulunalim, class isimleri herzaman buyuk harfler baslar
public int cadence;
public int gear;
public int speed;

// calssimizi yapilandiralim
public Bicycle(int gear, int speed, int cadence){
this.gear = gear;
this.speed = speed;
this.cadence = cadence;
//this kullanimina baska bir makalede uzun bir yer ayiracaz :)
}
//clasimizin methodlari
public void setCadence(int newValue){
cadence = newValue;
}
public void setGear(int newValue){
gear = newValue;
}
public void speedUp(int increment){
speed +=increment;
}
}
// simdi bicycle clasimizi MountainBike ile extends edeilim
public class MountainBike extends Bicycle{
public int seatHeight;

public MountainBike(int Height, int cadence, int speed, int gear){
// super kullaniminada ayireten deyinecez
super(cadence, speed, gear);
seatHeight = Height;

public void setHeight(int newValue){
seatHeight = newValue;
}
}
Bu ornegimiz faydali olmustur umarum, ama kalitim konusu dedigimiz cok onemli bir konu oldugu icin biraz daha uzerininde durmamiz gerekiyor....

Gizli Kalıtım

Oluşturduğumuz her yeni sınıf otomatik ve gizli olarak Object sınıfından türer. Object sınıfı Java programlama dili içerisinde kullanılan tüm sınıfların tepesinde bulunur. ()
public class YeniBirSinif {
public static void main(String[] args) {
YeniBirSinif ybs1 = new YeniBirSinif();
YeniBirSinif ybs2 = new YeniBirSinif();
System.out.println("YeniBirSinif.toString()" + ybs1 );
System.out.println("YeniBirSinif.toString()" + ybs2 ) ;
System.out.println("ybs1.equals(ybs2)"+ybs1.equals(ybs2)) ;
// ....
}
}
Uygulamamızın çıktısı aşağıdaki gibi olur:
YeniBirSinif.toString() YeniBirSinif@82f0dbYeniBirSinif.toString() YeniBirSinif@92d342ybs1.equals(ybs2) falseYeniBirSinif sınıfımızda, toString()ve equals() yordamları tanımlanmamasına rağmen bu yordamları kullandık, ama nasıl ? Biz yeni bir sınıf tanımladığımızda, Java gizli ve otomatik olarak extends Object, ibaresini yerleştirir. ()

Buradan su anlasiliyorki demekki biz her yazdigimiz uygulamda kalitim kullaniyoruz ama fark etmiyoruz, ama artik biliyoruz gizli kalitimin nasil bisey oldugunu...:)

ornekte verecek olursak hem daha iyi kavrariz hemde kullanabildfigmiz yordamlari ogrenmis oluruz.

public class YeniBirSinif extends Object {

Bu sayede Object nesnesine ait erişebilir yordamları kullanabiliriz. Object nesnesine ait yordamlar aşağıdaki gibidir: ()
clone() :Bu nesnenin(this) aynisini klonlar ve yeni nesneyi dondurur.
equals(Objesc obj) :obj referansina bagli olan nesnenin, kendisine(this) esit olup olmadigini kontrolunu yapar.
finalize() :Cop toplaycisi tarafindan silinmeden once calistirlan son yordam(method).
getClass() :Bu nesnenin caisma anindaki sinizf bilgilerini Class nesnesi seklinde geri dondurur.
hashClass() :Bu nesnenin has kodunu geri doner;
notify(): Bu nesnenin (this), monitöründe olan tek bir iş parçacığını (thread) uyandırır. (ilerleyen bölümlerde inceleyeceğiz) ()
· notifyAll(): Bu nesnenin (this), monitöründe olan tüm iş parçacıklarını (thread) uyandırır. (ilerleyen bölümlerde incelenecektir) ()
· toString(): Bu nesnenin (this), String tipindeki ifadesini geri döner. ()
· wait(): O andaki iş parçacığının (thread) beklemesini sağlar; Bu bekleme notify() veya notifyAll() yordamları sayesinde sona erer. ()
· wait (long zamanAsimi):O andaki iş parçacığının (thread), belirtilen süre kadar beklemesini sağlar (zamanAsimi); bu bekleme notify() veya notifyAll() yordamları sayesinde de sona erdirilebilir. ()
· wait (long zamanAsimi, int nanos):O andaki iş parçacığının (thread), belirtilen gerçek süre kadar (zamanAsimi+ nanos) beklemesini sağlar; bu bekleme notify() veya notifyAll() yordamları sayesinde de sona erdirilebilir. nanos parametresi 0-999999 arasında olmalıdır. ()
Kısacası, oluşturulan her yeni sınıf, yukarıdaki, yordamlara otomatik olarak sahip olur. Bu yordamları yeni oluşan sınıfların içerisinde tekrardan istediğimiz gibi yazabiliriz (uygun olan yordamları iptal edebiliriz-override). Örneğin finalize() yordamı kendi sınıfımızın içerisinde farklı sorumluluklar verebiliriz (çizgi çizen bir nesnenin, bellekten silinirken çizdiği çizgileri temizlemesi gibi). Bu olaya, ana sınıfın yordamlarını iptal etmek (override) denir.

Kalıtım ve İlk Değer Alma SırasıTek bir sınıf içerisinde ilk değerlerin nasıl alındığı 3. bölümde incelenmişti İşin içerisine birde kalıtım kavramı girince olaylar biraz karışabilir. Kalıtım (inheritance) kavramı bir sınıftan, başka bir sınıf kopyalamak değildir. Kalıtım kavramı, türeyen bir sınıfın, türetildiği sınıfa ait erişilebilir olan özellikleri alması ve ayrıca kendisine ait özellikleri tanımlayabilmesi anlamına gelir. Bir sınıfa ait nesne oluşurken, ilk önce bu sınıfa ait yapılandırıcının (constructor) çağrıldığını önceki bölümlerimizden biliyoruz. ()
Verilen örnekte, UcanYarasa nesnesi oluşmadan evvel, UcanYarasa sınıfının ana sınıfı olan Yarasa nesnesi oluşturulmaya çalışılacaktır. Fakat Yarasa sınıfıda Hayvan sınıfından türetildiği için daha öncesinde Hayvan sınıfına ait olan yapılandırıcı çalıştırılacaktır. Bu zincirleme giden olayın en başında ise Object sınıfı vardır. ()

IlkDegerVermeSirasi.java ()
class Hayvan {
public Hayvan() {
System.out.println("Hayvan Yapilandiricisi");
}
}
class Yarasa extends Hayvan {
public Yarasa() {
System.out.println("Yarasa Yapilandiricisi");
}
}
class UcanYarasa extends Yarasa{ public UcanYarasa() {
System.out.println("UcanYarasa Yapilandiricisi");
}
public static void main(String args[]) {
UcanYarasa uy = new UcanYarasa();
}
}


Object sınıfını bir kenara koyarsak, ilk olarak Hayvan sınıfının yapılandırıcısı çalışacaktır, daha sonra Yarasa sınıfının yapılandırıcısı çalışacaktır ve en son olarak UcanYarasa sınıfının yapılandırıcısı çalışacaktır. Bu yapılandırıcıların hepsi, fark edildiği üzere varsayılan yapılandırıcıdır (default constructor). Uygulamanın çıktısı aşağıdaki gibi olacaktır; ()
Hayvan YapilandiricisiYarasa YapilandiricisiUcanYarasa Yapilandiricisi

Parametre Alan Yapilandiricilar ve Kalitim
Ana sinifina ait yapilandirici cagirma islemi, varsayilan yapilandiricilar icin otomatik olarak yurtulen, parametere alan yapilandiricilar icin olay biraz daha degisiiktir. Kisaca Ana sinfin parametre alan yapilandiricisini acik olarak supr anahtar kelimesi ile cagirmak gereklidir. Soyle ki;

// bu ornegi dikkatlice inceleyelim ve super() kullanimia dikkat edin
Class Insan {
public Insan(int par){
System.out.println("Insan yapilandiricisi "+ par);
}
}

class ZekiInsan extends Insan{
public ZekiInsan(int par){
super(par+1);//dikkat
System.out.println("ZekiInsan Yapilandiricisi "+par);

}
}

class Hacker extends ZekiInsan{
public Hacker(int par){
super (par+1);//dikkat
System.out.println("Hacker yapilandiricisi "+par);
}
public static void main(String args[]){
Hacker hck = new Hacker(5);
}
}

Yukarıdaki örneğimizde, her sınıf, yapılandırıcısına gelen değeri bir arttırıp ana sınıfının yapılandırıcısına göndermektedir. Fark edildiği üzere ana sınıfın parametre alan yapılandırıcısını çağırırken super anahtar kelimesini kullandık. Uygulamanın çıktısı aşağıdaki gibidir. ()
Insan Yapilandiricisi 7
ZekiInsan Yapilandiricisi 6
Hacker Yapilandiricisi 5

Bu arda Onemli bir not, super() anahtar kelimesi herzaman bulundugu yapilandiricinin ilk satirda olmak zorundadir.

Komposizyon mu? Kalıtım mı?
Yeni oluşturduğunuz sınıfın içerisinde, daha evvelden yazılmış sınıfların özelliklerinden faydalanmak istiyorsanız bunun iki yolu olduğunu belirtmiştik; Komposizyon ve kalıtım. Peki hangi yöntemi ne zaman tercih etmeliyiz? Komposizyon, daha evvelden yazılmış sınıfların özelliklerini kullanmak için temiz bir yöntemdir.
Peki, kalıtım kavramı ne zaman kullanılır? Daha evvelden yazılmış bir sınıfın, belli bir problem için yeni versiyonunu yazma işleminde, kalıtım kavramı kullanılabilir. Fakat kalıtım konusunda türetilen sınıf ile türeyen sınıf arasında bir ilişki olmalıdır. Bu ilişki "bir" ilişkisidir. Örneğin Kedi ve Kaplan sınıflarını göz önüne alırsak, şöyle bir söz yanlış olmaz sanırım, Kaplan bir Kedidir. Bu iki sınıf arasında "bir" (is -a) ilişkisi olduğundan, kalıtım kavramını bu sınıflar üzerinde rahatça kullanabiliriz. ()
Örnekleri çoğaltmak mümkündür; UçanYarasa, Yarasa ve Hayvan arasındaki ilişki açıklanısa, ()
· UçanYarasa bir Yarasadır;
· Yarasa bir Hayvandır;
· O zaman UçanYarasa'da bir Hayvandır.
· Hayvan'da bir Nesnedir.

4 Aralık 2008 Perşembe

Java Interface

Interface Kavram?
Yaz?lan programramlarda Interface'lerin kullan?lmas?, dahas? OOP(Object Oriented Programming) kurallar?na uygun olarak kod yaz?lmas?, ilk olarak kod miktar? buyudukce yaz?lan class'lar?n hangi islevleri yerine getirdiginin bilinmek istenmesi sorununa futi kardesimin de dedigi gibi bir cevap olabilir.
Kodunuzda interface kullan?m?na giderseniz, size en buyuk yararlar?ndan biri, kabaca class'lar?n ne ise yarad?g?n?n kolayca ogrenilebilmesi de diyebilecegimiz, koda butun parcalar halinde bakabilmektir.Burdan kast etmek istedigim sey su; yazd?g?n?z program? tek bas?n?za gelistiriyorsan?z ve kod karmasas? da dusukse belki direkt faydas?n? goremeyebilirsiniz ancak bir tak?m halinde kod gelistiriyorsan?z buyuk bir class'?n tek bak?sta hangi islevleri yerine getirebildigini sizden baska birilerinin hemen kavrayabilmesi zor olabilir
Simdi ogulun babadan aldigi genlerin ilk etapla implementle ili$kisi yok. Oraya gelecegiz. Cünkü implement büyükbabayla baba arasinda.

Interface, icinde metod isimleri bulunan bir zorunluluk listesi gibidir. O interface'i implement eden sinif interface'in icinde adi gecen metodlarin hepsini gercellemek (to implement) zorundadir.

Yani Interface gen kalitimindan öte bir vasiyet gibidir. Büyük baba babaya eger benim oglum olmayi kabul ediyorsan bu $artlari (interface'deki metodlari) gercekle$tirmek zorundasin der. Baba Implements sözcügü ile bu vasiyeti kabul etmi$ olur ve $artlari (yani interface metodlarini) gercekle$tirir.

Extends ise cocugun babasindan dolayi sahip oldugu $eylerdir. Mesela cocugun kendine ait evi olmasi gerekmez. Cünkü babasinin evi vardir ve orada uyur. Babasinin evini, limuzinini, bankadaki parasini kullanir. Bunlar kendisine ait degildir ama babasin oldugu icin kullanma hakkina sahiptir. Bunlar tamamen babanin kendi kazanip edindigi mallar da olabilir, implements yoluyla büyükbabadan miras kalmi$ da olabilir. Cocuk icin hepsi aynidir. Sonucta nereden gelmi$ olursa olsun bu mallar babasinindir ve hepsinde kendisi de kullanim hakkina sahiptir.

Java'da interface, bir class'ta olmas? gereken method ve property'leri tan?mlayan yap?d?r. Kendisi normal bir class degildir, sadece neyin yap?lacag?n? gostermekte, ancak nas?l yap?lacag?n? gostermemektedir. Ornek olarak, bir madde'de ne gibi islevler ve ozellikler olmas? gerektigini belirten bir interface yazal?m.

Matter.javaIndir Goster Gizle Kopar Sat?r Gizle Sat?r Goster

public interface Matter{
public double getVolume();
public double getMass();
}


Bu ifade, 'bir maddenin yogunlugu, hacmi ve kutlesi olur' demenin Java'daki yoludur. Ancak goruldugu gibi maddenin yogunlugu nas?l hesaplan?r, kutlesi nas?l verilir, hic bir sekilde belirtmemektedir. Sadece ne olmas? gerktigini soylemektedir.

Interface'in Implementation'u
Bir class'?n interface'deki butun method'lar? icerdigini, gerceklestirdigini belirtmesine implementation denir ve 'implements' keyword'uyle kullan?l?r.

CubeMatter.javaIndir Goster Gizle Kopar Sat?r Gizle Sat?r Goster

public class CubeMatter implements Matter{
public double density=1.0;
public double edge=1.0;
public double getDensity(){
return density;
}
public double getVolume(){
return edge*edge*edge;
}
public double getMass(){
return density*edge*edge*edge;
}
}


Burada "Kup diye bir nesnemiz var ve o bir maddedir, yani bir maddede olabilecek butun nitelikler onda da bulunur." demis olduk ve bunlar?n nas?l hesapland?g?n? gosterdik. Ayn? interface'i implement eden baska bir class'da yap?labilir.

SphereMatter.javaIndir Goster Gizle Kopar Sat?r Gizle Sat?r Goster

public class SphereMatter implements Matter{
public double density=1.0;
public double radius=1.0;
public double getDensity(){
return density;
}
public double getVolume(){
return (3.14 * radius * radius * radius )/3;
}
public double getMass(){
return density*(3.14 * radius * radius * radius )/3;
}
}
Goruldugu gib bu class'da ayn? interface implement ediyor. Ancak hacim ve kutle hesaplamas? cok degisik
interfacle`rin nasil bi kolaylik sagladigini asagidaki adreste cok guzel anlatilmis
http://jtpd.org/docs/strategy_design_pattern.pdf
----
Interfaceeri kullanmak icin icin bi kac ornek yazalim
public interface DoIt {
void doSomething(int i, double x);
int doSomethingElse(String s);
}

public interface DoIt {

void doSomething(int i, double x);
int doSomethingElse(String s);
boolean didItWork(int i, double x, String s);

}

public interface DoItPlus extends DoIt {

boolean didItWork(int i, double x, String s);

}
Bunlarda interfaceleri tekrar nasil kullanabiliriz onlar hakkinda bi kac ornekdi :), Ama sunu soylemek istiyorum ki java ogrenebicegimiz en iyi yer Sun`nin itesidir.
Interfacelerin anlatildigi bolumun linki asagisdadir,
http://java.sun.com/docs/books/tutorial/java/IandI/interfaceAsType.html

28 Kasım 2008 Cuma

Pl/Sql

Dynamic SQL, runtime'de oluşturulan bir SQL'in çalıştırılmasıdır. Normalde programlarda veya PL/SQL bloklarında sorgu yazarken hard code olarak yazıp çalıştırılan SQL'ler static SQL'dir. Örneğin SQL*Plus üzerine yazdığımız bütün SQL'leri dynamic SQL ile çalıştırır. Dynamic SQL kavramı kullanım örneklerinden sonra daha anlaşılır olacaktır. • Dynamic SQL esnektir, kullanımı büyük esneklik sağlar, Ama Static SQL kullanmak çoğu zaman daha performanslı olacağı için static SQL ile yapılabilecek şeyleri static SQL ile yapmalı, dynamic SQL'i mecbur olduğunda kullanmalıdır. • Dynamic SQL'i ne zaman kullanırız? Run-time'da sorgularımızın inputlara gre veya başka şartlarda değişebileceği durumlarda veya DDL çalıştırmak için kullanırız. (Normalde PL/SQL bloğu içinde DDL çalıştırılamıyor) • Dynamic SQL, PL/SQL içinde iki şekilde kullanılabilir: Birincisi EXECUTE IMMEDIATE komutu ile, ikincisi ise DBMS_SQL paketi ile. Execute Immediate ile DML'leri, DDL'leri, PL/SQL bloklarını, Transaction Control komutlarını ve Session Control komutlarını kolaylıkla çalıştırabilirsiniz. Bu komut, sorgunun dinamik olarak runtime'da parse edilip çalıştırılmasını sağlar. DBMS_SQL paketi ise, biraz daha gelişmiş özellikleri barındırır. Daha çok özel amaçlarla kullanılır. Örneğin, sorgudan dönen kolon isimleri veya kolon sayısı gibi bir bilgi lazım olunca DBMS_SQL paketi kullanılabilir. Fakat daha fazla özellik barındırmayısla birlikte, kullanımı biraz daha zordur ve biraz daha yavaş çalışır. DBMS_SQL paketinin kullanımı ile ilgili ayrıntılı bilgiyi referanslarda da bulabilirsiniz. Her iki kullanım örneklerini de sunumda bulabilirsiniz. • Native Dynamic SQL(EXEC. IMMED.)'in avantajları: 1- Kullanımı kolaydır.2- Daha hızlı çalışır.3- Kullanıcı tanımlı tipleri destekler.4- Dönen kayıtları RECORD'lar içine atabilir. • DBMS_SQL paketinin avantajları: 1- Input ve output sayısı bilinmediğinde de kullanılabilir.2- Select'ten dönecek kolon sayısı veya isimleri belli olmadığında da çalıştırılabilir.3- 32KB'dan daha uzun sorguları da çalıştırabilir.4- Tekrar kullanılabilirliği sağlar. • Amacımız genellikle performans ve kolaylık avantajını yaklamak olduğu için, yapabildiğimiz herşeyi EXEC. IMMED. ile yapmamız daa mantıklı. Ama DBMS_SQL paketine gerçekten ihtiyacımız olan durumlr da oluyor, bu yüzden bu paketi ve yetkinliklerini bilmemiz de önemli.