XML Tool – XStream

XStream
Eğer bir süredir kod yazıyorsanız, yani kastetmek istediğim derslerde yazdığınız ödevler değil, iş hayatında size proje olarak verilmiş programlar, mutlaka XML dosyalarını, en azından program ayarlarınızı almak ve saklamak için kullanmışsınızdır. Sizinde farkettiğiniz üzere aldığınız bu ayarları ya da başka bilgileri, kodunuzun içinde aktarırken nesnelere ihtiyaç duyarsınız. Fakat XML dosyasını okumak ve bunu nesneye dönüştürmek gerçekten çok sıkıcı bir iştir. İlk yaptığınızda yeni birşey öğrendiğiniz için ilginizi çekebilir fakat sonradan cidden sıkıcı bir hal almaya başlar. Hatta bazı ayarları XML’den okumaya üşenmenize kadar gidebilir bu durum.

İşte XStream tam da bu noktada işinize yarayacak bir araç. Eğer bu zamana kadar çoktan kendi generic XML okuma classlarınızı yarattıysanız birşey diyemem fakat, benim gibi yeni yeni yaratmayı düşünüyorsanız XStream tam size göre. Bense elimden geldiği şekilde size XStream’i bir örnek üzerinden anlatmaya çalışacağım.

XStream kelimenin tam anlamıyla, Xml’den nesneye, nesnelerden ise Xml’e dönüşüm yapmanızı kolaylaştıran bir araç.

Peki bu anlatım neleri kapsıyor?

  • Öncelikle projemizde kullanacağımız örnek bir veritabanı ayarlarını barındıran bir class yaratacağız. Pek gerçekçi bir ayar olmayacak fakat herkese tanıdık gelmesi açısından böyle temayı seçtim.
  • Sonra bu class yapsını xml dosyasına nasıl kaydedeceğimizi göreceğiz.
  • Son olarakta önceden oluşturduğumuz xml yapısındaki bir bilgiyi nesneye nasıl alacağımıza bakacağız.

Herşeyden önce ben anlatımımda Eclipse Helios IDE’sini kullanacağım. Öncelikle XStream sitesinden XML aracımızı indiriyoruz. Sonra bunu, Eclipse’te oluşturduğumuz java projemize ekliyoruz. Proje üzerinde sağ tıkladıktan sonra açılan pencerede Build Path seçeneğinden istediğiniz şekilde ekleyebilirsiniz. Ben User Libraries şeklinde eklemeyi tercih ediyorum. Burdan devam etmeden önce tavsiyem XStream sitesindeki iki dakikalık örneği bir incelemeniz. Ben kendi örneğimde XStream Tutorial diye bir proje oluşturdum ve bunun üzerinden devam edeceğim anlatmaya.

Veritabanı Ayarlarını Barındıran Class Yapıları

XStream Tutorial projesinde, src klasörünün altında “blg.bhdrkn.first” isimli bir paket oluşturdum ve bu paketin altına ise aşağıdaki class yapılarımı yarattım.

Authentication.java


package blg.bhdrkn.first;

public class Authentication {

private String userName;
private String password;

public Authentication(String userName, String password) {
super();
this.userName = userName;
this.password = password;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

@Override
public String toString() {
return "Authentication [userName=" + userName + ", password="
+ password + "]";
}

}

Configuration.java


package blg.bhdrkn.first;

import java.util.Arrays;

public class Configuration {

private String dataBaseHostAddress;
private Authentication dbAuth;
private String[] dataBases;
private String toExtraFilePath;

public Configuration(String dataBaseHostAddress, Authentication dbAuth) {
super();
this.dataBaseHostAddress = dataBaseHostAddress;
this.dbAuth = dbAuth;
}

public String getDataBaseHostAddress() {
return dataBaseHostAddress;
}

public void setDataBaseHostAddress(String dataBaseHostAddress) {
this.dataBaseHostAddress = dataBaseHostAddress;
}

public Authentication getDbAuth() {
return dbAuth;
}

public void setDbAuth(Authentication dbAuth) {
this.dbAuth = dbAuth;
}

public String[] getDataBases() {
return dataBases;
}

public void setDataBases(String[] dataBases) {
this.dataBases = dataBases;
}

public String getToExtraFilePath() {
return toExtraFilePath;
}

public void setToExtraFilePath(String toExtraFilePath) {
this.toExtraFilePath = toExtraFilePath;
}

@Override
public String toString() {
return "Configuration [dataBaseHostAddress=" + dataBaseHostAddress
+ ", dbAuth=" + dbAuth + ", dataBases="
+ Arrays.toString(dataBases) + ", toExtraFilePath="
+ toExtraFilePath + "]";
}
}

Nesneden XML’e

Böylelikle ayarlarımı tutacağım class yapılarımı oluşturdum.  Şimdi ise bu class yapılarımı xml dosyasına yazacak olan XMLFactory class’ımı oluşturacağım. Şimdilik sadece nesneden xml dosyasına nasıl çevireceğime bakacağım. Sonraki kısımlarda bu class’a geri dönüp xml’den nesneye nasıl çevireceğimide ekleyeceğim. XMLFactory.java dosyamı, oluşturduğum “blg.bhdrkn.first.xstream” paketinin içine yaratıyorum.

XMLFactory.java


package blg.bhdrkn.first.xstream;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import blg.bhdrkn.first.Authentication;
import blg.bhdrkn.first.Configuration;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class XMLFactory {

private XStream xStream = null;

public XMLFactory() {
this.xStream = new XStream(new DomDriver());
this.xStream.alias("Configuration", Configuration.class);
this.xStream.alias("Authentication", Authentication.class);
this.xStream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
}

public String toXmlString(Configuration config) {
return this.xStream.toXML(config);
}

public void toXmlFile(Configuration config, String xmlPath) {
try {
File file = new File(xmlPath);
file.createNewFile();
FileWriter writer = new FileWriter(file);
BufferedWriter bufferedWriter = new BufferedWriter(writer);
this.xStream.toXML(config, bufferedWriter);
} catch (IOException e) {
e.printStackTrace();
}
}

// İleride başka method'larda eklenecektir... Xml'den Nesneye dönüşüm yapan method vb.

Öncelikle constructor kısmında ne yaptığımdan bahsediyim. Bu kısımda nesnelerimin hangi kelimelerle temsil edileceğini belirtiyorum. Class adıyla aynı olması tamamen benim seçtiğim bir şeydir siz isterseniz başka şekilde de seçebilirsiniz. Eğer böyle bir seçim yapmazsanız muhtemelen class’ınızın tam adını kullanacaktır. Yani bulunduğu paketin ve classınızın adını aralarına nokta koyarak kullanacaktır. DomDriver kullanmamın tek sebebi ise başka xml okuma yapılarına bağımlılık duymak istememem. Başka bir yapıda kullanabilir ya da boş bırakabilirsiniz. Fakat bağımlılıklarını eklemeniz gerekecektir.

Nesneden XML’e Dönüsüm Yapan Metodların Test Edilmesi

Şimdi ise sırada XMLFactory class’ımda kullandığım metodların test edilmesi var. Bunun için öncelikle “blg.bhdrkn.first.test” paketini oluşturuyorum. Ardından bu paketin içine aşağıdaki Class’ımı Main metodu ile birlikte oluşturuyorum.

XStreamObjectToXml.java


package blg.bhdrkn.first.test;

import blg.bhdrkn.first.Authentication;
import blg.bhdrkn.first.Configuration;
import blg.bhdrkn.first.xstream.XMLFactory;

public class XStreamObjectToXml {

public static void main(String[] args) {
String[] dataBases = { "WordPress1", "WordPress2", "WordPress3", "WordPress4", "WordPress5" };
XMLFactory factory = new XMLFactory();
Configuration config = new Configuration("localhost", new Authentication("bhdrkn", "wordPress"));
config.setDataBases(dataBases);
config.setToExtraFilePath("../extraFilePath.txt");

ObjectToXmlString(config, factory);
ObjectToXmlFile(config, factory);
}

private static void ObjectToXmlString(Configuration config,
XMLFactory factory) {
String xmlString = factory.toXmlString(config);
System.out.println(xmlString);
}

private static void ObjectToXmlFile(Configuration config, XMLFactory factory) {
factory.toXmlFile(config, "config.xml");
}
}

Bu testin kısaca ne yaptığından bahsetmek gerekirse, öncelikle bize Configuration nesnesi yaratıyor. Sonra bunu ekrana basıyor ve ardından ise yarattığı “config.xml” isimli bir dosyaya bu bilgileri yazıyor. Çalıştırdığınızda aşağıdakine benzer bir çıktı almanız bekleniyor.


<Configuration>
 <dataBaseHostAddress>localhost</dataBaseHostAddress>
 <dbAuth>
 <userName>bhdrkn</userName>
 <password>wordPress</password>
 </dbAuth>
 <dataBases>
 <string>WordPress1</string>
 <string>WordPress2</string>
 <string>WordPress3</string>
 <string>WordPress4</string>
 <string>WordPress5</string>
 </dataBases>
 <toExtraFilePath>../extraFilePath.txt</toExtraFilePath>
 </Configuration>

Bundan başka ise projenizin ana dizininde config.xml isimli bir dosyanın ekran çıktıyısla aynı içerikle yaratılması gerekiyor. Eğer projenizde config.xml dosyasını göremiyorsanız projenizi yenilemelisiniz. [F5]

XML’den Nesneye

Şimdi ise sıra XML’den nesneye dönüşüm yapmaya geldi. Bunun için öncelikle config2.xml isimli bir dosyayı projemizin ana dizininde (config.xml dosyasının yaratıldığı yerde) yaratmanız gerekiyor. Dosyayı yarattıktan sonra içeriğini aşağıdaki ile değiştiriniz.


<Configuration>
 <dataBaseHostAddress>192.168.1.1</dataBaseHostAddress>
 <dbAuth>
 <userName>wordPress</userName>
 <password>Passw0rd</password>
 </dbAuth>
 <dataBases>
 <string>WordPress6</string>
 <string>WordPress7</string>
 <string>WordPress8</string>
 <string>WordPress9</string>
 <string>WordPress10</string>
 </dataBases>
 <toExtraFilePath>/extraFilePath.txt</toExtraFilePath>
 </Configuration>

Dosyayı kaydedip kapatınız. Yine daha önce oluşturduğumuz XMLFactory.java dosyasını açıyoruz. Açtıktan sorna ise aşağıdaki yeni metodumuzu class’ımıza ekliyoruz.

XMLFactory.java


// Önceden oluşturduğumuz Constructor, toXmlString, toXmlFile metodları duruyor

public Configuration fromXmlFile(String xmlPath) {
Configuration config = null;
try {
File file = new File(xmlPath);
FileReader reader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(reader);
config = (Configuration) this.xStream.fromXML(bufferedReader);
} catch (IOException ex) {
ex.printStackTrace();
}
return config;
}

Xml’den Nesne’ye Dönüsüm Yapan Metodların Test Edilmesi

Bu methodun test edilmesi için yine “blg.bhdrkn.first.test” paketi altına aşağıdaki classımızı yaratıyoruz.

XStreamXmlToObject.java


public static void main(String[] args) {
XMLFactory factory = new XMLFactory();
Configuration config = factory.fromXmlFile("config2.xml");
System.out.println(config);
}

Bu class’ımızı çalıştırdığımızda ise aşağıdaki çıktıyı almanız bekleniyor.

Configuration [dataBaseHostAddress=192.168.1.1, dbAuth=Authentication [userName=wordPress, password=Passw0rd], dataBases=[WordPress6, WordPress7, WordPress8, WordPress9, WordPress10], toExtraFilePath=/extraFilePath.txt]

Son Olarak

Umarım biraz da olsa XML okumak gibi sıkıcı bir konuda size yardımcı olabilmişimdir.

End Of Line