<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1447805187508565242</id><updated>2012-01-09T05:18:54.712-08:00</updated><category term='ruby'/><category term='linux'/><category term='gökova'/><category term='veritabanı'/><category term='istanbul'/><category term='JIRA'/><category term='scalability'/><category term='cache'/><category term='acceptance test'/><category term='Physics'/><category term='Hibernate'/><category term='CVS'/><category term='versiyonlama sistemi'/><category term='Java Eğitimi'/><category term='parameters'/><category term='Mylyn'/><category term='XML'/><category term='temiz kod'/><category term='Java'/><category term='db2'/><category term='ie'/><category term='scuba diving'/><category term='annotation'/><category term='Seminer'/><category term='yaşam'/><category term='kiteboard'/><category term='agile'/><category term='flash builder'/><category term='flex 4'/><category term='jetty'/><category term='Maven'/><category term='Apache Wicket'/><category term='Wicket'/><category term='JAXB'/><category term='shortcuts'/><category term='kanban'/><category term='eclipse'/><category term='canon eos 500d'/><category term='Spring'/><category term='rdesktop'/><category term='JTPD'/><category term='Applet'/><category term='bodrum'/><title type='text'>Taner Diler's Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>38</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-2314966368583198189</id><published>2012-01-09T02:39:00.000-08:00</published><updated>2012-01-09T02:40:36.551-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Ubuntu'da /tmp dizininin otomatik silinmesini engellemece</title><content type='html'># sudo vim /etc/default/rcS&lt;br /&gt;&lt;br /&gt;Change from:&lt;br /&gt;&lt;br /&gt;TMPTIME=0&lt;br /&gt;&lt;br /&gt;To:&lt;br /&gt;&lt;br /&gt;TMPTIME=1&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-2314966368583198189?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/2314966368583198189/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=2314966368583198189' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/2314966368583198189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/2314966368583198189'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2012/01/ubuntuda-tmp-dizininin-otomatik.html' title='Ubuntu&apos;da /tmp dizininin otomatik silinmesini engellemece'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-6556123742820913899</id><published>2011-12-19T08:25:00.000-08:00</published><updated>2012-01-09T05:18:54.731-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Ubuntu üzerinde Ruby On Rails kurulumu yapmak</title><content type='html'>Ubuntu 10.04 üzerinde Ruby kurulumu gerçekleştireceğiz.&lt;br /&gt;&lt;br /&gt;sudo apt-get install aptitude&lt;br /&gt;sudo aptitude update&lt;br /&gt;sudo aptitude  install build-essential git-core curl&lt;br /&gt;bash &lt; &lt;(curl -s https://rvm.beginrescueend.com/install/rvm)&lt;br /&gt;echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] &amp;&amp; source "$HOME/.rvm/scripts/rvm"' &gt;&gt; ~/.bashrc&lt;br /&gt;&lt;br /&gt;. ~/.bashrc&lt;br /&gt;&lt;br /&gt;rvm requirements&lt;br /&gt;&lt;br /&gt;/usr/bin/apt-get install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion&lt;br /&gt;&lt;br /&gt;sudo /usr/bin/apt-get install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion&lt;br /&gt;&lt;br /&gt;rvm install 1.9.2&lt;br /&gt;rvm use 1.9.2&lt;br /&gt;ruby -v&lt;br /&gt;rvm --default use 1.9.2&lt;br /&gt;&lt;br /&gt;$rvm gemset create YOUR_GEMSET_NAME&lt;br /&gt;$rvm 1.9.2@YOUR_GEMSET_NAME&lt;br /&gt;$gem install bundler&lt;br /&gt;&lt;br /&gt;$ gem install rails --no-rdoc --no-ri&lt;br /&gt;$ rails new RAIL_APP&lt;br /&gt;&lt;br /&gt;Edit Gemfile &lt;br /&gt;add/edit this group definition&lt;br /&gt;&lt;br /&gt;group :development, :test do&lt;br /&gt;  gem 'rspec-rails'&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;$ bundle install&lt;br /&gt;&lt;br /&gt;$ sudo apt-get update&lt;br /&gt;# Install needed packages&lt;br /&gt;$ sudo apt-get install git-core curl build-essential openssl libssl-dev&lt;br /&gt;# Install node.js&lt;br /&gt;$ git clone https://github.com/joyent/node.git &amp;&amp; cd ~/Development/NodeJS&lt;br /&gt;$ ./configure&lt;br /&gt;$ make&lt;br /&gt;$ sudo make install&lt;br /&gt;$ cd&lt;br /&gt;# Install npm&lt;br /&gt;$ curl http://npmjs.org/install.sh | sudo sh&lt;br /&gt;#Install CoffeeScript&lt;br /&gt;$ sudo  npm install -g coffee-script&lt;br /&gt;&lt;br /&gt;$ sudo apt-get install libmysql-ruby libmysqlclient-dev&lt;br /&gt;#change gem 'sqlite3' to gem 'mysql2' in Gemfile&lt;br /&gt;$ bunlder install&lt;br /&gt;&lt;br /&gt;$ rake db:create&lt;br /&gt;&lt;br /&gt;#make slim as a default template add this "Slim::Engine.set_default_options :sections =&gt; true" line to config/environment.rb&lt;br /&gt;&lt;br /&gt;Create a migration file of exist schema, run this command; this command generates a file in db/schema. Last command reload schema, you can see the effect on schema_migrations table.&lt;br /&gt;$ rake db:schema:dump RAILS_ENV=development&lt;br /&gt;$ rake db:schema:load&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-6556123742820913899?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/6556123742820913899/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=6556123742820913899' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/6556123742820913899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/6556123742820913899'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2011/12/ubuntu-uzerinde-ruby-on-rails-kurulumu.html' title='Ubuntu üzerinde Ruby On Rails kurulumu yapmak'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-692614453385515360</id><published>2011-12-09T01:12:00.000-08:00</published><updated>2011-12-09T01:43:24.274-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kanban'/><title type='text'>Kanban Ruhu</title><content type='html'>Şu sıralar "Kanban - Successful Evolutionary for Your Tech Business" kitabını okuyorum. Kanban kavramına şu an çalıştığım yerde ilgili olmaya başladım ama aslında bu sistemi daha önce çalıştığım yerde ruhumuzda oluşturmuşuz zaten. Scrum süreç yönetimini uygulayan bir şirketin ufak parçalara ayrılmasından sonra adı Scrum olmayan ama yime Project Owner, Tester, Developer birimlerinden - her biri bir/iki kişiden - oluşan bir süreç oluşturmuştuk kendimize. Developer yazar, Tester test eder, Project Owner müşteri ile - müşteri parçalanma sonrasında iş veren oldu - konuşur ve iş birimlerini yönetirdi.&lt;br /&gt;&lt;br /&gt;Developer ekibi iki kişiden oluşmaktaydı. Bunlardan biri de bendim. İki kişi de farklı projelerden sorumluydu. Lakin şöyle bir sıkıntımız mevcuttu. İki farklı proje ama aynı context altında hizmet vermekte ve aynı trunk üzerinde mergeler geliştirilmekteydi. Bir hikaye tamamlanır tamamlanmaz deployment gerçekleşirdi ama deployment süreci branch'lerin merge edilmesi, merge'den kaynaklanan sorunların tespiti v.b. yaklaşık bir günümü alıyordu. Haftada birkaç kez releaase'lerin çıkması ciddi şekilde iş kaybına neden oluyordu. Bunu çözmemiz gerekiyordu ve bunun için cuma günlerini deployment günü ilan ettik. Her hafta cuma günü düzenli bir şekilde deployment'i gerçekleştiriyorduk.&lt;br /&gt;&lt;br /&gt;Bir sonraki haftanın ilk günü ise geçen hafta yapılan çalışmanın özeti ve yapılacakların tartışıldığı bir toplantı yapıyorduk. Bu toplantıda tasarımcı, tester, yazılımcı, project owner ve müşteri bulunuyordu. Böylelikle müşterinin sürekli güncel olması sağlanıyordu.Bu toplantıda o hafta backlog'daki listemizden maaliyetine göre nelerin yapılacağı veya yeni hangi özelliklerin eklenmesi gerektiği tartışılıyordu.&lt;br /&gt;&lt;br /&gt; Mevcut sistem içerisinde değişimi yine kendimiz gerçekleştirmiş ve yönetmiş olduk. Kanban mevcut sistemdeki sıkıntıları görmek ve direnci min. seviyede tutarak değişim uygulamak için ideal bir sistem. Bir ritim anlayışını oluşturmakta ve WIP'e limitler koyarak sıkıntıları yönetilebilir hale getirmektedir.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-692614453385515360?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/692614453385515360/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=692614453385515360' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/692614453385515360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/692614453385515360'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2011/12/kanban-ruhu.html' title='Kanban Ruhu'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-4776426187752130429</id><published>2011-08-14T05:14:00.000-07:00</published><updated>2011-08-21T23:33:46.404-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Sending Basecamp Worklogs to Campfire with Ruby</title><content type='html'>We collects all system notifications at Campfire Chat Room. We decide to send worklogs entered to Campfire. I wrote the code under. I choosed Ruby Programming Language for fast development. &lt;br /&gt;&lt;br /&gt;&lt;pre class="ruby" name="code"&gt;&lt;br /&gt;#!/usr/bin/ruby&lt;br /&gt;&lt;br /&gt;require 'rubygems'&lt;br /&gt;require 'rexml/document'&lt;br /&gt;require 'date'&lt;br /&gt;&lt;br /&gt;include REXML&lt;br /&gt;&lt;br /&gt;$_37SIGNAL_ACCOUNT="YOUR 37 SIGNALS ACCOUNT_NAME"&lt;br /&gt;$CAMPFIRE_TOKENACCESS_KEY="YOUR CAMPFIRE ACCESS TOKEN"&lt;br /&gt;$CAMPFIRE_ROOM_ID="YOUR ROOM ID"&lt;br /&gt;$BASECAMP_TOKENACCESS_KEY="YOUR BASECAMP ACCESS TOKEN"&lt;br /&gt;&lt;br /&gt;class TimeEntryIdFile &lt;br /&gt;	def self.read&lt;br /&gt;		lastWorkLogId = 0&lt;br /&gt;		if File.exist? "/tmp/last.worklog.id" then&lt;br /&gt;			File.open('/tmp/last.worklog.id', 'r')  do |f1|&lt;br /&gt;			   while line = f1.gets&lt;br /&gt;			      lastWorkLogId = line&lt;br /&gt;			   end&lt;br /&gt;			end&lt;br /&gt;			return lastWorkLogId&lt;br /&gt;		end&lt;br /&gt;	end&lt;br /&gt;&lt;br /&gt;	def self.update(lastId)&lt;br /&gt;		File.open('/tmp/last.worklog.id', 'w').write(lastId)&lt;br /&gt;	end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Campfire&lt;br /&gt;	def self.sendMessage(message)&lt;br /&gt;		message = message.gsub("'", "-")&lt;br /&gt;		`curl -u #{$CAMPFIRE_TOKENACCESS_KEY}:X -H 'Content-Type: application/json' -d '{\"message\":{\"body\":\"#{message}\"}}' https://#{$_37SIGNAL_ACCOUNT}.campfirenow.com/room/#{$CAMPFIRE_ROOM_ID}/speak.json`&lt;br /&gt;	end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class BaseCamp&lt;br /&gt;    BASECAMP_API_COMMAND="curl -k -u #{$BASECAMP_TOKENACCESS_KEY}:X -H 'Accept: application/xml' -H 'Content-Type: application/xml' https://#{$_37SIGNAL_ACCOUNT}.basecamphq.com"&lt;br /&gt;    &lt;br /&gt;    def self.project(projectId)&lt;br /&gt;    	projectDoc = `#{BASECAMP_API_COMMAND}/projects/#{projectId}.xml` &lt;br /&gt;        doc = Document.new(projectDoc)&lt;br /&gt;        return Project.parse(doc.root)&lt;br /&gt;    end  &lt;br /&gt;&lt;br /&gt;    def self.person(personId)&lt;br /&gt;        personDoc = `#{BASECAMP_API_COMMAND}/people/#{personId}.xml`&lt;br /&gt;        doc = Document.new(personDoc)&lt;br /&gt;        return Person.parse(doc.root)&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    def self.todo(todoItemId)&lt;br /&gt;        todoDoc = `#{BASECAMP_API_COMMAND}/todo_items/#{todoItemId}.xml`&lt;br /&gt;        doc = Document.new(todoDoc)&lt;br /&gt;        return ToDo.parse(doc.root)&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    def self.todoList(todoListId)&lt;br /&gt;        todoListDoc = `#{BASECAMP_API_COMMAND}/todo_lists/#{todoListId}.xml`&lt;br /&gt;	doc = Document.new(todoListDoc)&lt;br /&gt;&lt;br /&gt;        return ToDoList.parse(doc.root)&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    def self.timeEntries ()&lt;br /&gt;	  	timeXmlDoc = `#{BASECAMP_API_COMMAND}/time_entries/report.xml`&lt;br /&gt;		doc = Document.new(timeXmlDoc)&lt;br /&gt;		timeEntries = Array.new&lt;br /&gt;		doc.root.each_element('//time-entry') {|timeEntryElement| timeEntries.push(TimeEntry.parse(timeEntryElement)) }&lt;br /&gt;		return timeEntries&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;	def self.timeEntriesFrom(lastTimeEntryId)&lt;br /&gt;		puts "last time entry id #{lastTimeEntryId}"&lt;br /&gt;		lastTimeEntries = Array.new&lt;br /&gt;		timeEntries = BaseCamp.timeEntries()&lt;br /&gt;&lt;br /&gt;		timeEntries.each {|timeEntry| &lt;br /&gt;			if lastTimeEntryId.nil? or lastTimeEntryId == 0 or timeEntry.id &gt; lastTimeEntryId then lastTimeEntries.push(timeEntry) end&lt;br /&gt;		}&lt;br /&gt;		return lastTimeEntries&lt;br /&gt;	end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class ToDoList &lt;br /&gt;	def initialize(name)&lt;br /&gt;		@name=name	&lt;br /&gt;	end&lt;br /&gt;&lt;br /&gt;	def self.parse(xmlElement)&lt;br /&gt;		return ToDoList.new(xmlElement.elements["name"].text)&lt;br /&gt;	end&lt;br /&gt;&lt;br /&gt;	def name() &lt;br /&gt;		return @name&lt;br /&gt;	end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class ToDo&lt;br /&gt;	def initialize(content, listId)&lt;br /&gt;		@content=content&lt;br /&gt;		@listId=listId&lt;br /&gt;	end&lt;br /&gt;	&lt;br /&gt;	def self.parse(xmlElement)&lt;br /&gt;		return ToDo.new(xmlElement.elements["content"].text, xmlElement.elements["todo-list-id"].text)&lt;br /&gt;	end&lt;br /&gt;	&lt;br /&gt;	def content()&lt;br /&gt;		return @content&lt;br /&gt;	end&lt;br /&gt;&lt;br /&gt;	def listId()&lt;br /&gt;		return @listId&lt;br /&gt;	end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Project&lt;br /&gt;	def initialize(name)&lt;br /&gt;		@name=name&lt;br /&gt;	end&lt;br /&gt;&lt;br /&gt;	def self.parse(xmlElement)&lt;br /&gt;		return Project.new(xmlElement.elements["name"].text)&lt;br /&gt;	end&lt;br /&gt;&lt;br /&gt;	def name()&lt;br /&gt;		return @name&lt;br /&gt;	end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Person&lt;br /&gt;	def initialize(firstName, lastName)&lt;br /&gt;		@firstName=firstName&lt;br /&gt;		@lastName=lastName&lt;br /&gt;	end&lt;br /&gt;&lt;br /&gt;	def self.parse(xmlElement)&lt;br /&gt;		return Person.new(xmlElement.elements["first-name"].text, xmlElement.elements["last-name"].text)&lt;br /&gt;	end&lt;br /&gt;&lt;br /&gt;	def name()&lt;br /&gt;		return @firstName +" "+@lastName&lt;br /&gt;	end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class TimeEntry &lt;br /&gt;    def initialize(id, personId, projectId, todoItemId, hours, desc, date)&lt;br /&gt;		@id=id&lt;br /&gt;        @personId = personId&lt;br /&gt;        @projectId = projectId&lt;br /&gt;	    @todoItemId = todoItemId &lt;br /&gt;        @hours = hours.to_f&lt;br /&gt;        @desc=desc&lt;br /&gt;        @date = date&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    def self.parse ( xmlElement )&lt;br /&gt;        timeEntry = TimeEntry.new(&lt;br /&gt;            xmlElement.elements["id"].text,&lt;br /&gt;			xmlElement.elements["person-id"].text, &lt;br /&gt;            xmlElement.elements["project-id"].text,&lt;br /&gt;			xmlElement.elements["todo-item-id"].text, &lt;br /&gt;			xmlElement.elements["hours"].text,&lt;br /&gt;			xmlElement.elements["description"].text,&lt;br /&gt;			xmlElement.elements["date"].text)&lt;br /&gt;		return timeEntry&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;	def id&lt;br /&gt;		return @id&lt;br /&gt;	end&lt;br /&gt;&lt;br /&gt;	def formattedDate()&lt;br /&gt;		return Date.strptime(@date, '%Y-%m-%d').strftime("%Y, %b %d")&lt;br /&gt;	end&lt;br /&gt;    &lt;br /&gt;    def hours&lt;br /&gt;    	if @hours == 0.5 then&lt;br /&gt;    	   return "yarim"&lt;br /&gt;    	elsif (@hours -@hours.floor) == 0.5 then &lt;br /&gt;    	   return @hours.floor.to_s + " bucuk"&lt;br /&gt;    	else &lt;br /&gt;           return @hours&lt;br /&gt;        end&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;	def message &lt;br /&gt;		person = BaseCamp.person(@personId)&lt;br /&gt;		project = BaseCamp.project(@projectId)&lt;br /&gt;		todo = BaseCamp.todo(@todoItemId)&lt;br /&gt;		todoList = BaseCamp.todoList(todo.listId)&lt;br /&gt;&lt;br /&gt;		message = "\\n\\nToDo List Name : " +todoList.name&lt;br /&gt;		message += "\\n\\n@WorkLog "+self.formattedDate()+"\\n\\n"+person.name+",\\n\\n"&lt;br /&gt;				&lt;br /&gt;		if @hours.to_f == 0.0 then&lt;br /&gt;			message += "hic ugrasmamis bir de worklog giriyor"&lt;br /&gt;		else&lt;br /&gt;			message += "'"+todo.content+"' isiyle "+self.hours().to_s+" saat ugrasmis"&lt;br /&gt;		end&lt;br /&gt;		&lt;br /&gt;		unless @desc.nil? then&lt;br /&gt;			message += ",\\n\\ndedi ki:\\n\\n"+@desc&lt;br /&gt;		end &lt;br /&gt;	&lt;br /&gt;		return message&lt;br /&gt;	end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;lastWorklogID=0&lt;br /&gt;lastWorklogID = TimeEntryIdFile.read()&lt;br /&gt;lastTimeEntries = BaseCamp.timeEntriesFrom(lastWorklogID)&lt;br /&gt;&lt;br /&gt;if lastTimeEntries.length !=0 then&lt;br /&gt;	campfireMessage = ""&lt;br /&gt;	lastTimeEntries.each {|timeEntry| campfireMessage = campfireMessage+"\\n"+timeEntry.message()}&lt;br /&gt;	&lt;br /&gt;	Campfire.sendMessage(campfireMessage)&lt;br /&gt;	TimeEntryIdFile.update(lastTimeEntries[0].id)&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-4776426187752130429?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/4776426187752130429/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=4776426187752130429' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/4776426187752130429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/4776426187752130429'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2011/08/sending-basecamp-worklogs-to-campfire.html' title='Sending Basecamp Worklogs to Campfire with Ruby'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-5972563725787501713</id><published>2011-07-30T13:56:00.000-07:00</published><updated>2011-08-26T06:39:35.096-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='temiz kod'/><title type='text'>Temiz Kod Yazımı : Anlamlı İsimlendirmeler</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-02jK_RP0x3Q/TleiDx3JrXI/AAAAAAAAANA/BUEGXd_IIKI/s1600/confusing.jpeg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 188px; height: 268px;" src="http://2.bp.blogspot.com/-02jK_RP0x3Q/TleiDx3JrXI/AAAAAAAAANA/BUEGXd_IIKI/s400/confusing.jpeg" border="0" alt=""id="BLOGGER_PHOTO_ID_5645158843740171634" /&gt;&lt;/a&gt;&lt;br /&gt;Kod yazarken oluşturduğumuz herşeye isim vermeye çalışırız. Bazen saatlerce düşünürüz acaba ne isim versem diye. Çünkü aynı ismi başka bir yerde kullanmışızdır. Yeni vereceğimiz isim bir öncekinin eklerler veya tamlamalarla çeşitlendirilmiş hali olabilir. Ama bütün gaye yeni olanı diğerinden ayıran anlamı birkaç kelime ile verebilmektir.&lt;br /&gt;&lt;br /&gt;Kod yazan kişi için verilen isim iç açıcı olabilir ama yukardan yani müşteri seviyesinde baktığımız da ne kadar iç açıcı olabilir! "Ben bunu anlamadım." şeklinde bir yaklaşımda bulunulduğunda yazmış olduğunuz eseri taşlıyorlarmış gibi hissedersiniz. Empati kurmaya başladığınızda anlarsınız ki evet gerçtekten hiçbir şey anlaşılmıyor. Artık Business seviyesinde yani patron, müşteri seviyesinde düşünüp ben burada bu değeri verebilmiş miyim diye tekrardan sormamız gerekiyor kendimize. Self-CodeReviewing diyebiliriz belki buna.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Domain-driven_design"&gt;Domain Driven Design&lt;/a&gt; bize business seviyesinde modelleme yapmamıza olanak sağlar. Wikipedia'da bakın nasıl tanımlanmış "&lt;font style="font-weight: bold; font-style: italic;"&gt;Domain-driven design (DDD) is an approach to developing software for complex needs by deeply connecting the implementation to an evolving model of the core business concepts.&lt;/font&gt;"&lt;br /&gt;InfoQ'da ki "Domain Driven Design and Development in Practice" isimli bir makale de ise "&lt;font style="font-style: italic; font-weight: bold;"&gt;Domain Driven Design (DDD) is about mapping business domain concepts into software artifacts.&lt;/font&gt;" olarak tanımlanmış.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;Amacı Açıklayan İsimlendirmeler (Intention Revealing Names)&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Yapılan isimlendirmeler şu soruya cevap vermeli "&lt;font style="font-weight: bold;"&gt;Bu ne için var, Ne yapıyor ve Nasıl kullanılmış&lt;/font&gt;". Eğer bir isimlendirmeye yönelik bir yorum/açıklama yazılmışsa koda, bilin ki o isimlendirme amacını açıklamıyor.&lt;br /&gt;&lt;br /&gt;Mesela:&lt;br /&gt;&lt;br /&gt;&lt;pre class="java" name="code"&gt;&lt;br /&gt;List&amp;lt;ogrenci&amp;gt; ogrenciler; // devamsızlığı olan öğrenciler&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ogrenciler isimlendirmesi yukarıdaki sorularımızın hiçbirine cevap vermiyor.&lt;br /&gt;&lt;br /&gt;Aşağıdaki gibi bir isimlendirme kullansaydık sorularımıza cevap verebilirdik ve yorum yazmaya da gerek kalmazdı.&lt;br /&gt;&lt;br /&gt;&lt;pre class="java" name="code"&gt;&lt;br /&gt;List&amp;lt;ogrenci&amp;gt; devamsizligiBulunanOgrenciler;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Peki aşağıdaki kod ne iş yapmaktadır?&lt;br /&gt;&lt;br /&gt;&lt;pre class="java" name="code"&gt;&lt;br /&gt;public List&amp;lt;int&amp;gt; icerisindeBul(List&amp;lt;int[]&amp;gt; kaynakListe){&lt;br /&gt;   List&amp;lt;int&amp;gt; liste1 = new ArrayList&amp;lt;int[]&amp;gt;;&lt;br /&gt;   for ( int[] oge : kaynakListe) {&lt;br /&gt;         if ( oge[1] == 2 ) {&lt;br /&gt;             liste1.add(oge[0]);&lt;br /&gt;         }&lt;br /&gt;   }&lt;br /&gt;   return liste1;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ne yaptığı anlaşılmakta gibi ama eğer bunu bir utility method olarak tanımlarsak. Bunun dışında bir listeden 2. elemanı 2 olan dizinin 1. elemanını başka bir dizi olarak geri döndürüyoruz. &lt;font style="font-weight: bold;"&gt;Ama neden???&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Soralım:&lt;br /&gt;&lt;br /&gt;1. kaynakListe içerisindeki tutulan değerler neyi ifade ediyor?&lt;br /&gt;2. kaynakListe içerisindeki dizilerin 2. elemanının ne gibi bir özelliği var?&lt;br /&gt;3. karşılaştırma 2 değeri neyi ifade ediyor?&lt;br /&gt;4. Döndürülen listeyi ben nasıl kullanacağım?&lt;br /&gt;&lt;br /&gt;Bu soruların hiçbirine cevap veremiyoruz değil mi?&lt;br /&gt;&lt;br /&gt;Kodumuzu şöyle yazsaydık:&lt;br /&gt;&lt;br /&gt;&lt;pre class="java" name="code"&gt;&lt;br /&gt;public List&amp;lt;int&amp;gt; devamsizlikYapanOgrencilerinNolariniGetir(List&amp;lt;int[]&amp;gt; kayitliTumOgrenciler){&lt;br /&gt;   List&amp;lt;int&amp;gt; ogrenciNolari = new ArrayList&amp;lt;int[]&amp;gt;;&lt;br /&gt;   for ( int[] ogrenci : kayitliTumOgrenciler) {&lt;br /&gt;         if ( devamsizlikYapanOgrenciMi (ogrenci)  ) {&lt;br /&gt;             ogrenciNolari .add(oge[0]);&lt;br /&gt;         }&lt;br /&gt;   }&lt;br /&gt;   return ogrenciNolari ;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;şimdi tüm sorularımıza cevap verebiliyoruz. Ayrıca "oge[1] == 2" karşılaştırmasını yardımcı bir methoda taşıyarak bu kodun 100% anlamlı olmasını sağladık.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;Yanlış Bilgiden Kaçınılmalı&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Bazen yazmış olduğumuz platform ve teknolojiye ait kodlarımızın içerisinde o an anlamlı olabilecek ama başka bir zamanda bize bile anlamsız gelecek ifadeler kullanabiliriz. Bir Unix platformu için yapacağımız kod çalışmasında scp, ssh gibi; JDBC kodlaması yapıyorsak ResultSet'in kısaltılmış hali olan rs gibi kısaltmalar kullanmak mantıklı olabilir ama yine de anlamsızdırlar.&lt;br /&gt;&lt;br /&gt;Bazen verilen ifadelerin sonlarına - özellikle bu Collection yapılarında çok yapılıyor - veri tipi ekleniyor; ogrenciList, nameStr gibi... ogrenciList yerine ogrenciler ifadesinin kullanımı anlamlı olacaktır. ogrenciList olarak ifade edilen bir yapı gerçekte List tipinde olmayabilir. OgrenciList bir sınıf tipi de olabilir. Burada gereksiz eklentiler yanlış bilgilendirmeye neden olmaktadır.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;İsimlendirmelerde Anlamlı Farklılıklar Oluşturun&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Kullandığımız dilin getirdiği kurallar nedeni ile isimlendirmeleri çeşitlendirmemiz gerekiyor. Aynı alanda (scope) aynı değişken ismini farklı tipler için birkaç kez kullanamıyoruz. Sırf derleyiciyi memnun etmek için bu sefer eklerle veya karakterle ayrımı yapmak zorunda kalıyoruz.&lt;br /&gt;&lt;br /&gt;Derleyiciyi memnun etmek için neler yapıyoruz:&lt;br /&gt;&lt;br /&gt;Değişken isminin başına veya sonuna &lt;font style="font-weight: bold;"&gt;"_" karakteri&lt;/font&gt; koyuyoruz. Eğer aynı isimden çok kullanmamız gerekirse bakın ne hale gelecek : "araba_______" :D&lt;/li&gt;&lt;li&gt;Data, Info gibi kelimeler ekleyerek kelime çeşitliliği sağlanır ama aslında hepsi aynı anlamdır. &lt;font style="font-weight: bold;"&gt;ogrenci&lt;/font&gt;, &lt;font style="font-weight: bold;"&gt;ogrenciBilgisi&lt;/font&gt;, &lt;font style="font-weight: bold;"&gt;ogrenciVerisi &lt;/font&gt;hepsi aynı. &lt;/li&gt;&lt;li&gt;"a", "the" kullanamıyla çeşitliliği sağlarız. Bir bakıma bu, parametre ile lokal değişkeni birbirinden ayırır. Anlam olarak yine bir ayrım söz konusu değildir.&lt;/li&gt;&lt;li&gt;Yazılımcı getOgrenci(), getOgrenciBilgisi() methodlarından hangisini çağıracak. Çünkü ikisi de aynı.&lt;/li&gt;&lt;/ol&gt;&lt;font style="font-weight: bold;"&gt;Söylenebilir  İsimler Kullanın&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Söylenebilir isimler kullanmak retrospektif toplantılarında R2D2 gibi sesler çıkarmamızı engeller.  Mesela arayüz kodlarında çok kullanılan &lt;font style="font-weight: bold;"&gt;wysiwyg  &lt;/font&gt;kısaltmasını kullanırsak bunu söylerken nasıl bir duruma düşeceğimizi hayal edebilirsiniz.&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;&lt;br /&gt;Aranılabilir Kelimeler Kullanın&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;Bundan önce bahsettiğimiz kurallar bu kurala zaten uymamıza neden olmaktadır.&lt;font style="font-weight: bold;"&gt; &lt;/font&gt;Kısaltmalar, anlamsız isimlendirmeler bizi aranılabilir bir içerikten uzaklaştıracaktır.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;&lt;font style="font-weight: bold;"&gt;&lt;font style="font-weight: bold;"&gt;&lt;/font&gt;&lt;/font&gt;Arayüz (Interface) ve Gerçekleştirici (Implementer) İsimlendirmeleri&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;Arayüz ile gerçekleştirici arasındaki ayrımı nasıl yaparsınız? Sizin için önemli olan arayüz mü yoksa gerçekleştirici mi?&lt;br /&gt;&lt;br /&gt;Kimileri arayüzleri gerçekleştiricilerinden şu şekilde ayırır "IHesapMakinasi" kimileri de gerçekleştiriciyi arayüzden şu şekilde ayırır "HesapMakinasiImp". Peki hangisini seçmeli?&lt;br /&gt;&lt;br /&gt;Birbiri ile network üzerinen konuşan iki sistem yaptığınızı düşünün. Nesneleri serialize edip network üzerinden gönderelim. Gelen byte kodları deserialize yapıldığında elimizde bir nesne olacaktır ama bu nesne hangi tipte olduğunu alıcı JVM bilmiyor.  Bunun için bir tanımlayıcı gerekmektedir. Siz arayüz tanımını alıcı tarafa verdiyseniz kolaylıkla bunu gerçek tipine dönüştürebilir. Bu durumda bizim için önemli olan arayüz (interface). Arayüze gerçek bir isim verirsem onun gerçekleştiricilerinin ne olduğu önemsiz kalır.&lt;font style="font-weight: bold;"&gt; &lt;/font&gt;Bu durumda arayüzü "HesapMakinasi" olarak adlandırmamız gerekecek. Gerçekleştiriciyi isterseniz "HesapMakinasiImpl" veya "BasitHesapMakinasi" / "MuhendisHesapMakinasi" / "GelismisHesapMakinasi" olarak adlandırabilirsiniz.&lt;br /&gt;&lt;br /&gt;Editörlerde dosyaların isimlerine göre sıralandığını düşünürsek "HesapMakinasi" ve "HesapMakinasiImpl" hep alt alta olacaktır.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight:bold;"&gt;Fantastik Kelimelerden Kaçının&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Hiç unutmuyorum performans analizi yaptığımız bir uygulamayı yazarken ileriye yönelik tahmin modülü için &lt;span style="font-weight: bold;"&gt;FortuneTeller&lt;/span&gt; ismini koymuştum. "Clean Code" kitabını okuduktan sonra yanlış bir kullanım yaptığımın farkına vardım.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Her Amaç İçin Tek Kelime&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Projeye başlamadan önce kendi standartlarınızı belirleyin. Bu standartlar içerisinde kullanacağınız genel kelimelerde bulunmalıdır. Örneğin fetch, get, retrieve kelimelerinin hepsi aynı anlama gelmektedir. Bir standartınız yoksa hangi methodun ne için çağrılacağı ve oluşturulacağı bilinemez. get methodunu bir sınıfın özelliklerine erişmek için kullanabilirsiniz bu bir JEE standartı ve birçok editör, 3th party API'lar bu standarta uyulduğunu varsaymaktadır.&lt;br /&gt;&lt;br /&gt;Controller, Manager gibi kelimeler daha çok yapılar arasındaki iletişimi yönetmektedirler. Manager, Controller kelimesi gördüğünüzde orada mutlaka genel birşeyler yapılmaktadır ve mutlaka içerisi yönetilemeyece şekilde şişmiştir. Bu kelimelerin kullanımı bir &lt;a href="http://en.wikipedia.org/wiki/Anti-pattern"&gt;antipattern&lt;/a&gt;'dir.&lt;br /&gt;&lt;br /&gt;Eğer iki değeri birleştirip yeni bir nesne oluşturan bir methodunuz varsa bu method'a &lt;span style="font-weight: bold;"&gt;"add"&lt;/span&gt; ismini koyabilirsiniz. Aynı sistemde bir değeri bir diziye ekleme işlemi için &lt;span style="font-weight: bold;"&gt;"add"&lt;/span&gt; kullanamazsınız. &lt;span style="font-weight: bold;"&gt;"append"&lt;/span&gt; veya &lt;span style="font-weight: bold;"&gt;"insert"&lt;/span&gt; daha anlamlı bir kullanım olacaktır.&lt;br style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-5972563725787501713?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/5972563725787501713/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=5972563725787501713' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/5972563725787501713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/5972563725787501713'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2011/07/temiz-kod-yazm-anlaml-isimlendirmeler.html' title='Temiz Kod Yazımı : Anlamlı İsimlendirmeler'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-02jK_RP0x3Q/TleiDx3JrXI/AAAAAAAAANA/BUEGXd_IIKI/s72-c/confusing.jpeg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-2303369533079181932</id><published>2011-07-30T06:45:00.001-07:00</published><updated>2011-07-30T08:27:08.708-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='temiz kod'/><title type='text'>Temiz Kod Yazımı Nasıl Olmalı?</title><content type='html'>Şu sıralar Robert C. Martin tarafından yazılmış "&lt;a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882"&gt;Clean Code&lt;/a&gt; kitabını okuyorum. Kitaba temiz kodun ne anlama geldiğini ünlü kodculara sorarak başlamış. &lt;br /&gt;&lt;br /&gt;- &lt;a href="http://www2.research.att.com/~bs/"&gt;Bjarne Stroustrup&lt;/a&gt; (C++'ı geliştiren ve "The C++ Programming" kitabının yazarı) : Temiz kod birşeyi en iyi şekilde yapmalıdır. Hata yönetimi ve mimarisi etkili, kolay geliştirilebilir ve performansı yüksek olmalıdır. &lt;br /&gt;&lt;br /&gt;- &lt;a href="http://en.wikipedia.org/wiki/Grady_Booch"&gt;Grady Booch&lt;/a&gt;, "&lt;a href="http://www.amazon.com/Object-Oriented-Analysis-Design-Applications-2nd/dp/0805353402"&gt;Object Oriented Analysis and Design with Applications&lt;/a&gt;" kitabının yazarı : Temiz kod basit ve ne yaptığını direkt göstermelidir. İyi yazılmış bir yazı gibi okunabilmelidir.&lt;br /&gt;&lt;br /&gt;- &lt;a href="http://www.davethomas.net/"&gt;"Big" Dave Thomas&lt;/a&gt;, OTI'nin yaratıcısı ve Eclipse stratejisinin babası: Temiz kodu okunabilir ve orijinal kodcusundan başka bir kodcu tarafından geliştirilebilir olmalıdır. Bir şeyi yapmak için birden fazla yol yerine tek bir çözüm yolunu sunmalıdır.&lt;br /&gt;&lt;br /&gt;Söylemlerden de görüldüğü gibi temiz kod; basit, okunabilen ve tek iş yapandır. Kod yazarken şu soruyu sorabilirsiniz kendinize "Yazılımla ilgisi olmayan biri bu kodu okduğunda ne yaptığını anlayabilir mi?". Eğer hayır ise demekki karmaşık ve okunamayan kod yazıyorsunuz demektir.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-2303369533079181932?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/2303369533079181932/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=2303369533079181932' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/2303369533079181932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/2303369533079181932'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2011/07/temiz-kod-yazm-nasl-olmal.html' title='Temiz Kod Yazımı Nasıl Olmalı?'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-1005862094057414898</id><published>2011-07-28T07:23:00.000-07:00</published><updated>2011-09-30T04:16:09.760-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='acceptance test'/><title type='text'>Web Uygulaması İçin Otomatik Kabul Testi Yazımı</title><content type='html'>Otomatik Kabul Testi &lt;a href="http://tanerdiler.blogspot.com/2011/07/otomatik-kabul-testi-auto-acceptance.html"&gt;nedir&lt;/a&gt; ve &lt;a href="http://tanerdiler.blogspot.com/2011/07/otomatik-kabul-testi-automated.html"&gt;nasıl olmalı&lt;/a&gt; sorularına daha önceki yazılarımda bahsetmiştim ve test kodu yazımında uymamız gereken kurallara değinmiştim. Bu kurallara gerçekleştirim seviyesinde yenilerini ekleyeceğiz. &lt;br /&gt;&lt;br /&gt;Bu yazımdaki anlatımda biraz daha domain seviyesinde olaylara bakacağız. Bu yüzden bazı gerçekleştirimleri UML diyagramları üzerinden anlatacağım.&lt;br /&gt;&lt;br /&gt;Elimizde bir blog uygulaması olsun. Bu blog uygulamasını ziyaret eden normal kullanıcılar ve blog girişlerini yapan admin kullanıcısı olsun.&lt;br /&gt;&lt;br /&gt;[User]-(looksAtListOfBlockEntrySummary)&lt;br /&gt;[User]-(looksAtBlogEntry)&lt;br /&gt;(looksAtListOfBlockEntrySummary)&amp;gt;(visitsHomePage)&lt;br /&gt;(looksAtBlogEntry)&amp;gt;(clicksBlogEntrySummary)&lt;br /&gt;[Admin]-(login)&lt;br /&gt;(login)&amp;gt;(visitsHomePage)&lt;br /&gt;(login)&amp;gt;(fillsLoginForm)&lt;br /&gt;[Admin]-(entersNewBlog)&lt;br /&gt;(entersNewBlog)&amp;gt;(clicksNewEntryTab)&lt;br /&gt;&lt;br /&gt;Aşağıdaki diyagramda bir ziyaretçinin yapacağı hareketleri görebilirsiniz.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-WDy71I3fmA8/ToIJvLDplOI/AAAAAAAAANo/PK1iMz-aeZ8/s1600/182f9ab.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 88px;" src="http://2.bp.blogspot.com/-WDy71I3fmA8/ToIJvLDplOI/AAAAAAAAANo/PK1iMz-aeZ8/s400/182f9ab.png" alt="" id="BLOGGER_PHOTO_ID_5657094787957363938" border="0"&gt;&lt;/a&gt;&lt;ol&gt;&lt;li&gt;Bir blog sayfasını açar &lt;/li&gt;&lt;li&gt;Anasayfada tanımlı blog girişlerinin özetleri listelenmiştir&lt;/li&gt;&lt;li&gt;Bu özetlerden birine tıkladığında tam halini görmektedir&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Aşağıdaki diyagramda ise bir yöneticinin yapacağı hareketleri görebilirsiniz:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-_C24tphDNok/ToILHUH7YlI/AAAAAAAAANw/KeWzSszAnIw/s1600/1884fbb6.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 143px;" src="http://1.bp.blogspot.com/-_C24tphDNok/ToILHUH7YlI/AAAAAAAAANw/KeWzSszAnIw/s400/1884fbb6.png" alt="" id="BLOGGER_PHOTO_ID_5657096302219715154" border="0"&gt;&lt;/a&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Blog sitesini açar&lt;/li&gt;&lt;li&gt;Login formunu doldurur&lt;/li&gt;&lt;li&gt;Yeni Giriş tabına tıklar&lt;/li&gt;&lt;li&gt;Blog girişini yapar&lt;/li&gt;&lt;li&gt;Ayrıca ziyaretçinin yaptığı tüm hareketleri yapar&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Yukarıdaki gereksinimlere baktığımızda domain modelleri neler olduğu kendisini belli etmektedir.&lt;br /&gt;&lt;br /&gt;Admin kullanıcısının 5. gereksiniminde bir iş kuralı (business-rule) vardır ve ilerde kod tekrarına neden olabilir. 5. maddede oluşabilecek kötü kokuları şimdiden almamız gerekir.&lt;br /&gt;&lt;font size="4"&gt;&lt;br style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;Önce Çağır Sonra Gerçekleştir&lt;/span&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Burada bir kural daha oluşmakta. Esnek bir test kodu yazmak için belki de öncelikle neyi istediğinizi yazmanız gerekmekte. Bunu yaptıkça gerçekleştirimde nasıl bir yol izleyeceğinizi kurgulayabilirsiniz.&lt;br /&gt;&lt;br /&gt;Blog uygulamasında ziyaretçi gereksinimlerini ele alalım. Test etmek istediğim gereksinimler:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Anasayfa blog girişlerinin özetlerini listeler&lt;/li&gt;&lt;li&gt;Blog özetine tıklandığında o girişin detayı görüntülenir&lt;/li&gt;&lt;li&gt;Blog Detay Sayfası blog girişinin tamamını görüntüler&lt;/li&gt;&lt;/ol&gt;Bu gereksinimlere ait test kodunu aşağıdaki gibi görmek isterim:&lt;br /&gt;&lt;br /&gt;1. Gereksinim için&lt;br /&gt;User.visitsHomePage();&lt;br /&gt;assertThat(homePage(), listsBlogEntrySummaries());&lt;br /&gt;&lt;br /&gt;2. Gereksinim için&lt;br /&gt;User.visitsHomePage().clicksAnySummary().waitFor(five.seconds());&lt;br /&gt;assertThat(user, visitsBlogDetailPage());&lt;br /&gt;&lt;br /&gt;lastClickedBlogSummary = homepage.lastClickedSummary();&lt;br /&gt;assertThat(blogDetailPage(), displaysFullBlogEntry().of(lastClickedBlogSummary ));&lt;br /&gt;&lt;br /&gt;3. Gereksinim için&lt;br /&gt;&lt;br /&gt;blogEntry = blogEntry().withId(5);&lt;br /&gt;User.visitsBlogDetailPage().forA(blogEntry);&lt;br /&gt;assertThat(blogDetailPage(), displaysFullBlogEntry().of(blogEntry));&lt;br /&gt;&lt;br /&gt;İş gereksinimlerini hiçbir yorum yazma gereksinimi duymadan anlaşılır bir şekilde kodlayabildim.&lt;br /&gt;&lt;br /&gt;User.visitsHomePage().clicksAnySummary().waitFor(five.seconds());&lt;br /&gt;&lt;br /&gt;şeklindeki bir çağrımda visitsHomePage() methodu bir static factory method olup sonraki methodlar User sınıfına ait bir nesneye aittir.&lt;br /&gt;&lt;br /&gt;assertThat(blogDetailPage(), displaysFullBlogEntry().of(blogEntry));&lt;br /&gt;&lt;br /&gt;şeklindeki çağrımda ise static import yapılarak sadece method isimleri görünmektedir. Bu statik methodları içerikle ilişkili olan bir sınıf içerisinde barındırabilirsiniz. &lt;a href="http://joe.truemesh.com/blog/000511.html"&gt;assertThat()&lt;/a&gt; methodu junit'in bir methodudur. İkinci parametre olarak bir &lt;a href="http://code.google.com/p/hamcrest/"&gt;Hamcrest&lt;/a&gt; projesine ait Matcher almaktadır. Siz istediğiniz şekilde kendi  mathcer'larınızı oluşturabilirsiniz.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;" size="5"&gt;Genel Web Bileşenleri Tanımlayın&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Yukarıdaki gereksinim testlerine ait kodlar sürekli değişime uğrayarak daha esnek hale gelecektir. Bu kodlarda beni rahatsız eden bir iki şey var.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;" size="4"&gt;Ziyaret Edilebilir Web Sayfası Bileşeni Tanımlayın&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Kullanıcı sürekli tekrar eden ve sayfa çeşitlemesine bağlı olarak tekrarlayan visits*() methodunu kullanmakta. Ziyaret edilen sayfa üzerinden daha sonrasında bazı sorgulamalar yapılmakta. Ben burada Page olgusu oluşturmam gerektiğini anlıyorum.&lt;br /&gt;&lt;br /&gt;[Page|url] &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-PJYEc6TVZyk/ToVhuPLZi4I/AAAAAAAAAN4/MPjPL_75Zwc/s1600/15b22bd4.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 93px; height: 59px;" src="http://1.bp.blogspot.com/-PJYEc6TVZyk/ToVhuPLZi4I/AAAAAAAAAN4/MPjPL_75Zwc/s400/15b22bd4.png" alt="" id="BLOGGER_PHOTO_ID_5658035953837116290" border="0"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;şeklinde yapı oluşturduktan sonra sayfa ziyaretleri şu hale gelecektir:&lt;br /&gt;&lt;br /&gt;User.visits(the.homepage());&lt;br /&gt;User.visits(the.entryDetailPage());&lt;br /&gt;&lt;br /&gt;the yardımcı sınıfı içerisinde yardımcı factory methodlar tanımlayabiliriz.&lt;br /&gt;&lt;br /&gt;public static homePage () {&lt;br /&gt;   return Page.forA("http://www.myblog.com");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;şeklinde Page nesnelerimizi oluşturabiliriz.&lt;br /&gt;&lt;br /&gt;Yukarıda 3. gereksinim için yazdığımı test çağrımında bir sıkıntımız bulunmakta.&lt;br /&gt;&lt;br /&gt;User.visitsBlogDetailPage().forA(blogEntry);&lt;br /&gt;&lt;br /&gt;Bu çağrım şekli bir blog girişi için detay sayfasının oluşturumunu User sınıfına yüklemektedir. Halbu ki User'in böyle bir sorumluluğu olamaz. Page yapısını oluşturduktan sonra bu çağrım şekli&lt;br /&gt;&lt;br /&gt;User.visits(the.entryDetailPage().forA(blogEntry));&lt;br /&gt;&lt;br /&gt;olacaktır.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;" size="4"&gt;Web Bileşenleri Tanımlayın&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Bilgidiğimiz gibi Web uygulaması bir çok temel bileşenin bir araya gelerek oluşturduğu bileşenlerden oluşmaktadır. Mesela kullanıcı giriş formu, blog özeti, blog özet listesi, blog detayı v.b. Yukarıdaki sayfa ziyaretinde olduğu gibi her bir bileşen için bir method tanımlamak anlamsız olacaktır.&lt;br /&gt;&lt;br /&gt;Önceki gereksinimlerimizde clicksAnySummary() methodu kötü kokular yaymaktadır. click event'i mouseover, mouseout gibi genel bir methoddur ve bu işlemler bir web bileşeni için çalışmaktadır. Bu methodların PageElement isminde bir yapıdan türemiş bileşenler üzerinde çalışması daha mantıklı gibi. Gereksinimlerimize bakarak aşağıdaki web bileşeni diyagramını oluşturabiliriz.&lt;br /&gt;&lt;br /&gt;[PageElement]^[LoginForm]&lt;br /&gt;[PageElement]^[EntrySummary]&lt;br /&gt;[PageElement]^[EntrySummaries]&lt;br /&gt;[PageElement]^[BlogEntryLink]&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-5PqKhVCwLJY/ToWk3OUF_NI/AAAAAAAAAOI/kKwyvOljTZ4/s1600/32adbba2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 135px;" src="http://1.bp.blogspot.com/-5PqKhVCwLJY/ToWk3OUF_NI/AAAAAAAAAOI/kKwyvOljTZ4/s400/32adbba2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5658109775503031506" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Web bileşenlerini tanımladıktan sonra çağrımlarımız bu şekilde olacaktır:&lt;br /&gt;&lt;br /&gt;User.visits(the.homepage()).clicks(the.homepage().anyBlogSummary());&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;" size="4"&gt;Web Bileşenlerinin Yüklenmesini Ana Bileşenlerin Sorumluluğuna Verin&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;Bir sayfadaki bileşenleri Page nesnesi yüklemeli ve bileşen sorgulamasını Page üzerinden yapın the.homepage().hasAnyEntrySummary() çağrımında olduğu gibi.&lt;br /&gt;&lt;br /&gt;EntrySummary bileşeni de detay sayfasına yönlendirecek link, özet bilgi ve başlık içermektedir. Bir EntrySummary nesnesi oluşturulurken bu alt bileşenleri yüklemeli. Böylece şu çağrımı yapabilirim:&lt;br /&gt;&lt;br /&gt;String entrySummaryText = the.homepage().selectAnyEntrySummary().content();&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-1005862094057414898?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/1005862094057414898/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=1005862094057414898' title='1 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/1005862094057414898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/1005862094057414898'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2011/07/web-uygulamas-icin-otomatik-kabul-testi.html' title='Web Uygulaması İçin Otomatik Kabul Testi Yazımı'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-WDy71I3fmA8/ToIJvLDplOI/AAAAAAAAANo/PK1iMz-aeZ8/s72-c/182f9ab.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-8903304028288527250</id><published>2011-07-27T04:51:00.000-07:00</published><updated>2011-07-28T06:30:47.413-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='acceptance test'/><title type='text'>Otomatik Kabul Testi (Automated Acceptance Test) Yazarken Dikkat Edilmesi Kurallar</title><content type='html'>Otomatik Kabul Testleri yazımında dikkat edilmesi ve unutulmaması gereken birkaç kural vardır. Bu kurallara uymak test kodların kırılganlığını ve çalışabilirliliğini artıracaktır.&lt;br /&gt;&lt;br /&gt;Ne kadar basit bir uygulama olursa olsun mutlaka bir 3th party bir api'a bağımlılığı olacaktır. Uygulama büyüdükçe veritabanı, birbiri ile iletişime geçen sistemler, dışarıdan kullanılan servisler kullanılmaya başlanılacaktır. Bu da uygulamanın kontrol edilebilirliliğini azaltacaktır.&lt;br /&gt;&lt;br /&gt;Yazılan test kodları iyi tasarlanmazsa ve test ekibinde copy/paste psikolojisi var ise test kodunun kırılganlığı artacaktır. Uygulama tarafında yapılan bir değişiklikte refactor edilecek kod miktarı gereğinden fazla olacaktır.&lt;br /&gt;&lt;br /&gt;Peki ben ne yapmalıyım ki ideal bir kabul test kodu yazayım?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;1. Application Driver ve GUI Driver (Web veya Form) yazmalıyım&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-a9Rdo1OLyD8/TjFj3gmqqbI/AAAAAAAAAMY/9p320K3U5Dc/s1600/OtomatikKabulTestleri.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 229px;" src="http://4.bp.blogspot.com/-a9Rdo1OLyD8/TjFj3gmqqbI/AAAAAAAAAMY/9p320K3U5Dc/s320/OtomatikKabulTestleri.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5634394414113270194" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Genel sistemin davranışını modelleyen bir api (Application Driver) ve kullanıcı arayüzünü modelleyen bir api yazmalıyım ki her yerden çağrabileyim. &lt;br /&gt;&lt;br /&gt;Mesela: Kullanıcın bir web uygulamasını açıp kullanıcı adını ve şifresini girip login olmasını bir web api yazarak modelleyebiliriz. Böylelikle login gerektiren diğer senaryoların testinde bu kod çağırılabilir.&lt;br /&gt;&lt;br /&gt;"Login olan kullanıcı bir alışveriş sitesinde elektronik kategorisindeki ürünleri listeler, beğendiklerini seçer ve bunları sepete koyar" şeklindeki bir senaryoya ait kabul testi yazmış olduğumuz WEB Driver sayesinde çok sade olacaktır.&lt;br /&gt;&lt;br /&gt;WebUser.login("username", "password").listsItemsIn(ELECTRONIC_CATEGORY).selectItemsRandomly().putsBasket();&lt;br /&gt;&lt;br /&gt;Application Api ile veritabanına test verisi yazma veya okuma işlemlerini gerçekleştirebiliriz.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;2. 3th party servislerle olan iletişimi modelle&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Facebook, Twitter gibi 3th party servisleri ile iletişim kurmak zorunda kaldığımız zamanlar olacaktır. Otomatik kabul testlerinde 3th party servislerle iletişim halinde olmak, testlerin çalışma zamanını uzatacak, 3th party servisin analitik verilerini etkileyecek, test kodumuzun güvenilirliliğini azaltacaktır (kullanılan servis sürekli değişim içerisinde olabilir).&lt;br /&gt;&lt;br /&gt;Bunun çözümü için gerçek servisi modelleyebiliriz. Yazacağımız bir yönetici yapı gerektiğinde gerçek servis yerine modeli ile iletişime geçmemizi sağlayacak. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-jTEw3UmglSA/TjFkcuNeh4I/AAAAAAAAAMg/pa1YFd26VyM/s1600/externalservis.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 204px;" src="http://4.bp.blogspot.com/-jTEw3UmglSA/TjFkcuNeh4I/AAAAAAAAAMg/pa1YFd26VyM/s320/externalservis.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5634395053420873602" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Böylece haftada bir kere gerçek servis üzerinden kabul testlerimizi çalıştırmayı sağlayabiliriz. Ayrıca servis modellerini farklı senaryolar için çeşitlendirebiliriz.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;3. Test ortamı kontrol edilebilir olmalı&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Veritabanı, Uygulama Sunucuları, arkada çalışan işler (batch jobs) v.b. uygulamayı oluşturan her yapı kontrol edilebilir olmalı. Uygulama sunucusu test kodu tarafından başlatılabilir ve durdurulabilir olmalı, veritabanına veri yazılabilir veya sıfırdan veritabanı oluşturulabilmeli. &lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;4. Test verileri için builder'lar oluşturulmalı (Test Data Builder)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Farklı senaryolar için verilerin çeşitlenmesi kaçınılmaz bir durumdur. Her bir durum için verileri oluşturan methodlar yazmak builder'i &lt;a href="http://c2.com/cgi/wiki?ObjectMother"&gt;Object Mother&lt;/a&gt; haline getirecektir. &lt;br /&gt;&lt;br /&gt;İdeal test verisi oluşturma yöntemi için &lt;a href="http://www.natpryce.com/articles/000728.html"&gt;bu&lt;/a&gt; ve &lt;a href="http://www.natpryce.com/articles/000724.html"&gt;şu&lt;/a&gt; yazıları okuyabilirsiniz.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;5. Test senaryosu ortamını sıfırlamalı&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Bir test senaryosu, bir önceki senaryonun etkisinde kalmamalı. Bu yüzden veritabanı, uygulama sunucusu gibi sistemleri sıfırlamalıdır. 3. kuralımız sayesinde her sistemi kontrol edebilir duruma gelmiştik.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;6. Genel otomatik kabul testi adımları&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Başlangıç koşulları oluşturulmalı : Gerekli veriler veritabanına yazılmalı, konfigurasyonlar yapılmalı, uygulama sunucu başlatılmalı...&lt;br /&gt;&lt;br /&gt;Test senaryosu gerçekleştirilmeli : Uygulamayı kullanan bir kullanıcının yaptığı adımlar Web/Application API'dan işletilmeli.&lt;br /&gt;&lt;br /&gt;Beklenen sonuç kontrol edilmeli : JUnit ile beklenen sonuç ile test sonucu karşılaştırılmalı. Burada önemli olan yazılan karşılaştırma kodunun müşteri tarafından okunabilir ve anlaşılabilir olmasıdır.&lt;br /&gt;&lt;br /&gt;assertEquals(15, urunSayisi); gibi bir kodun bir anlamı olmayacaktır.&lt;br /&gt;&lt;br /&gt;assertThat(basketPage().listsProduct(), count(equalsTo(5)) ); gibi bir yazım daha anlamlı olacaktır. &lt;a href="http://code.google.com/p/hamcrest/"&gt;Hamcrest&lt;/a&gt; anlamlı matcher kullanımları için inceleyebilirsiniz.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-8903304028288527250?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/8903304028288527250/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=8903304028288527250' title='2 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/8903304028288527250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/8903304028288527250'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2011/07/otomatik-kabul-testi-automated.html' title='Otomatik Kabul Testi (Automated Acceptance Test) Yazarken Dikkat Edilmesi Kurallar'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-a9Rdo1OLyD8/TjFj3gmqqbI/AAAAAAAAAMY/9p320K3U5Dc/s72-c/OtomatikKabulTestleri.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-8495919439421646194</id><published>2011-07-27T02:33:00.000-07:00</published><updated>2011-07-27T04:47:36.991-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='acceptance test'/><title type='text'>Otomatik Kabul Testi (Automated Acceptance Test)</title><content type='html'>Otomatik Kabul Testleri (Automated Acceptance Test) adından da anlaşılacağı gibi yapılan geliştirmenin onaylanmasına yönelik testlerdir. Müşterinin bize sunmuş olduğu gereksinimler onaylanma kriterlerini belirler. &lt;br /&gt;&lt;br /&gt;"Bir muhasebeci olarak daha iyi bir gider yönetimi yapmak için, geçmiş giderleri aylık olarak görmek istiyorum."&lt;br /&gt;&lt;br /&gt;İşte bu söylem üst düzey yani müşteri ve proje yönetisi arasında gerçekleşen bir diyalogtur. Bu da bizim kabul kriterimizi oluşturmaktadır. Bu kriter açıkça net ve hiçbir teknik unsur içermemektedir.&lt;br /&gt;Bu tarz söylemleri otomatik kabul testlerinde (Automated Acceptance Test) kullanmak için test ortamları bulunmaktadır, meselaRuby ve Java için versiyonları bulunan &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt;, &lt;a href="http://easyb.org/"&gt;EasyB&lt;/a&gt;, &lt;a href="http://jbehave.org/"&gt;JBehave&lt;/a&gt;. Bu test ortamları daha çok Davranışsal Güdümlü Geliştirme'yi(Behaviour Driven Development) olanak sağlar.&lt;br /&gt;&lt;br /&gt;Cucumber ile Türkçe olarak yazılmış gereksinim:&lt;br /&gt;&lt;br /&gt;# language: tr&lt;br /&gt;Özellik: Bölme&lt;br /&gt;Gülünç hatalardan sakınmak için&lt;br /&gt;Bir kasiyer sayıları bölebilmeli&lt;br /&gt;&lt;br /&gt;Senaryo: Doğal sayılar&lt;br /&gt;Diyelim ki hesap makinesine 3 girdim&lt;br /&gt;Ve hesap makinesine 2 girdim&lt;br /&gt;Eğer ki böl tuşuna basarsam&lt;br /&gt;O zaman ekrandaki sonuç 1.5 olmalı&lt;br /&gt;&lt;br /&gt;Yukarıdaki örnekten görüldüğü gibi bir uygulamadan istenilen tüm davranış girilmiş.&lt;br /&gt;&lt;br /&gt;Günümüzde birçok yazılım şirketinde uygulamaların sağlıklı çalışıp çalışmadığı kurulan bir test ekibi ile gerçekleşmektedir. Bu test ekibinin buz dağının görünmeyen yüzünde çok büyük bir maaliyeti vardır. Sürekli elle uygulama test edilmek zorunda ki bir günde bu uygulamanın tamamı nasıl test edilecek. Ayrıca sürekli geliştirmenin olduğu bir ortamda modüller arasındaki iletişimi de test etmek gerekir ki kişiler üzerindeki iş yükü gittikçe fazlalaşmaktadır. Ve unutmayalım ki insanız, gözümüzden kaçan bir sorun müşteriye kadar gidecektir.&lt;br /&gt;&lt;br /&gt;Otomatik Kabul Test'leri insan faktöründen kaynaklanan hataları minimize etmekte, daha hızlı ve etkin kontrol sağlamaktadır. Continuous Integration sunucuları ile entegre hale getirerek, release'ler öncesinde veya belli periyotlarla kabul testleri çalıştırılabilir.&lt;br /&gt;&lt;br /&gt;Proje yöneticileri ve şirket sahibi otomatik testlerin sonuçları karşısında yazılım ekibine ve kendisine olan özgüveni artacak. Her iterasyon sonrasında müşteri yapılan sunumlarda otomatik testlerin durumları paylaşılarak, projenin durumu hakkında genel bilgi verilmiş olunacak. &lt;br /&gt;&lt;br /&gt;Müşteri isteklerinin durumu hakkında elle tutulur bir veri olmasının getirdiği güven sayesinde projenin onaylanmasına kendinden ve uygulamadan emin olarak gidecektir.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-8495919439421646194?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/8495919439421646194/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=8495919439421646194' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/8495919439421646194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/8495919439421646194'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2011/07/otomatik-kabul-testi-auto-acceptance.html' title='Otomatik Kabul Testi (Automated Acceptance Test)'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-1616883876187861238</id><published>2011-02-24T02:02:00.000-08:00</published><updated>2011-02-24T02:17:30.146-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='acceptance test'/><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><title type='text'>Copying Maven Dependencies to Specific Location</title><content type='html'>I'm trying to establish our acceptance test environment by using maven. I created a separate project for acceptance tests. To have a controllable environment, I need to start web server via acceptance test code. So, I need to path of war file - depended from acceptance test project - to give embedded jetty starter code. There were two way to learn path of war file:&lt;br /&gt;&lt;br /&gt;first one is the getting path to war file that located on local repo&lt;br /&gt;      create a ${version} property of depended war artifact.&lt;br /&gt;      create a profile property by using ${settings.localRepository}/com/group/artifactname-${version}.war&lt;br /&gt;      send the path property as system property to test code&lt;br /&gt;      use this property on jetty start code like this&lt;br /&gt;webapp.setWar(PathToWarFile);&lt;br /&gt;&lt;br /&gt;another way is the copy dependencies under to target path of project&lt;br /&gt;      In order to that, I add the copy-dependencies goal of maven-dependency-plugin. This plugin copies all artifacts. For specific artifact, may be I create a plugin.&lt;br /&gt;      Other steps are same as above.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-1616883876187861238?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/1616883876187861238/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=1616883876187861238' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/1616883876187861238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/1616883876187861238'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2011/02/copying-maven-dependencies-to-specific.html' title='Copying Maven Dependencies to Specific Location'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-2022846414898737726</id><published>2011-02-04T00:52:00.000-08:00</published><updated>2011-07-27T02:48:03.110-07:00</updated><title type='text'>Shell Script dilinde Fonksiyon tanımlama</title><content type='html'>Bu içerik&lt;a href="http://viralpatel.net/blogs/2009/07/writing-functions-in-shell-script.html"&gt; http://viralpatel.net/blogs/2009/07/writing-functions-in-shell-script.html&lt;/a&gt; sayfasından alınmıştır.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Writing Functions in Shell Script&lt;/h1&gt;   &lt;ul class="postinfo"&gt;&lt;li&gt;By &lt;a href="http://viralpatel.net/blogs/author/viral/" title="Posts by Viral Patel"&gt;Viral Patel&lt;/a&gt; on July 9, 2009&lt;/li&gt;&lt;/ul&gt;Have you ever written a huge Unix script and thought you would have  divided this script into pieces of reusable code? Well don’t worry. You  can create &lt;strong&gt;functions in unix shell script&lt;/strong&gt; and  make reusable code and call the &lt;strong&gt;function&lt;/strong&gt; from your &lt;strong&gt;unix code&lt;/strong&gt;. &lt;h2&gt;Hello World Function in Unix shell script&lt;/h2&gt; &lt;p&gt;First let us see a simple code snippet for creating hello world function in Unix. Create a shell script file &lt;strong&gt;helloworld.sh&lt;/strong&gt; and paste following code in it and execute it. &lt;/p&gt; &lt;br /&gt;&lt;br /&gt;&lt;code style="bgcolor: #383838; "&gt;&lt;br /&gt;#function hello world defined&lt;br /&gt;fnHelloWorld()&lt;br /&gt;&lt;br /&gt;{        &lt;br /&gt;#print hello world&lt;br /&gt;        &lt;br /&gt;echo "Hello World";&lt;br /&gt;}&lt;br /&gt;#calling hello world function&lt;br /&gt;fnHelloWorld&lt;br /&gt; &lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt; &lt;div&gt;&lt;div id="highlighter_429829" class="syntaxhighlighter  cpp"&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div class="container"&gt;&lt;div class="line number1 index0 alt2"&gt;&lt;code class="cpp plain"&gt;$./helloworld.sh&lt;/code&gt;&lt;/div&gt;&lt;div class="line number2 index1 alt1"&gt;&lt;code class="cpp plain"&gt;Hello World&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt; &lt;p&gt;The above shell script will print &lt;em&gt;Hello World&lt;/em&gt; on command prompt. All we have done is we have defined a function in shell script by &lt;code&gt;fnHelloWorld() {}&lt;/code&gt; and called this by just &lt;strong&gt;fnHelloWorld&lt;/strong&gt;.&lt;/p&gt; &lt;h2&gt;Passing argument to function in shell scripts&lt;/h2&gt; &lt;p&gt;&lt;strong&gt;Passing argument&lt;/strong&gt; to the functions in shell script is  very easy. Just use $1, $2, .. $n variables that represent arguments in  the function. Following is the example of function that takes two  argument and prints them. Note that we have called the function  fnArgumentFunction and passed two arguments “Hello” and “World” by  fnArgumentFunction “Hello” “World”.&lt;/p&gt; &lt;div&gt;&lt;div id="highlighter_723688" class="syntaxhighlighter  cpp"&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div class="container"&gt;&lt;div class="line number1 index0 alt2"&gt;&lt;code class="cpp plain"&gt;fnArgumentFunction()&lt;/code&gt;&lt;/div&gt;&lt;div class="line number2 index1 alt1"&gt;&lt;code class="cpp plain"&gt;{&lt;/code&gt;&lt;/div&gt;&lt;div class="line number3 index2 alt2"&gt;&lt;code class="cpp spaces"&gt;        &lt;/code&gt;&lt;code class="cpp plain"&gt;echo &lt;/code&gt;&lt;code class="cpp string"&gt;"Argument 1:"&lt;/code&gt; &lt;code class="cpp plain"&gt;. $1&lt;/code&gt;&lt;/div&gt;&lt;div class="line number6 index5 alt1"&gt; &lt;/div&gt;&lt;div class="line number7 index6 alt2"&gt;&lt;code class="cpp spaces"&gt;        &lt;/code&gt;&lt;code class="cpp plain"&gt;echo &lt;/code&gt;&lt;code class="cpp string"&gt;"Argument 2:"&lt;/code&gt; &lt;code class="cpp plain"&gt;fnArgumentFunction &lt;/code&gt;&lt;code class="cpp string"&gt;"Hello"&lt;/code&gt; &lt;code class="cpp string"&gt;"World"&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt; &lt;p&gt;Thus if your function will use three arguments you can just use $1, $2 and $3 in your code.&lt;/p&gt; &lt;p&gt;You may want to use &lt;strong&gt;$#&lt;/strong&gt; which gives you number of arguments passed to the function if you want to implement a function with variable arguments.&lt;/p&gt; &lt;h2&gt;Returning values from Function in Shell Script&lt;/h2&gt; &lt;p&gt;Like passing arguments in function in shell script, returning values  are also easy. Following is the example of a function that take two  input string and returns the concatenated values. We store the return  parameter in a variable and print the variable on screen.&lt;/p&gt; &lt;div&gt;&lt;div id="highlighter_630697" class="syntaxhighlighter  cpp"&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div class="container"&gt;&lt;div class="line number1 index0 alt2"&gt;&lt;code class="cpp plain"&gt;fnReturnFunction()&lt;/code&gt;&lt;/div&gt;&lt;div class="line number2 index1 alt1"&gt;&lt;code class="cpp plain"&gt;{&lt;/code&gt;&lt;/div&gt;&lt;div class="line number3 index2 alt2"&gt;&lt;code class="cpp spaces"&gt;        &lt;/code&gt;&lt;code class="cpp plain"&gt;echo $1$2&lt;/code&gt;&lt;/div&gt;&lt;div class="line number4 index3 alt1"&gt;&lt;code class="cpp plain"&gt;}&lt;/code&gt;&lt;/div&gt;&lt;div class="line number5 index4 alt2"&gt;&lt;code class="cpp plain"&gt;value=$(fnReturnFunction &lt;/code&gt;&lt;code class="cpp string"&gt;"holly"&lt;/code&gt; &lt;code class="cpp string"&gt;"wood"&lt;/code&gt;&lt;code class="cpp plain"&gt;)&lt;/code&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt; &lt;p&gt;Note that in above example we have called the function by $(fnReturnFunction “holly” “wood”).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-2022846414898737726?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/2022846414898737726/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=2022846414898737726' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/2022846414898737726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/2022846414898737726'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2011/02/shell-script-dilinde-fonksiyon-tanmlama.html' title='Shell Script dilinde Fonksiyon tanımlama'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-3836926507338684691</id><published>2011-01-03T00:56:00.000-08:00</published><updated>2011-01-03T01:04:26.871-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='parameters'/><title type='text'></title><content type='html'>-Dmail.smtp.starttls.enable=true to instruct JAVA Mail to use TLS protocol&lt;br /&gt;-Dmail.pop3.port=993 to specify the pop3 port&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-3836926507338684691?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/3836926507338684691/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=3836926507338684691' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/3836926507338684691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/3836926507338684691'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2011/01/dmail.html' title=''/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-6008858563764410029</id><published>2010-12-27T01:04:00.000-08:00</published><updated>2010-12-27T01:08:33.208-08:00</updated><title type='text'>SVN Komutları</title><content type='html'>To List Committers in SVN Rep.&lt;br /&gt;&lt;div style="background-color: #CCC;"&gt;&lt;br /&gt;svn log --quiet SVN_REP_URL \&lt;br /&gt;| grep '^r' | awk '{print $3}' | sort | uniq &gt; committers.txt&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;To change committers name in SVN DUMP FILE&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: #CCC;"&gt;&lt;br /&gt;svnadmin dump path/to/my/repo &gt; repo.dump&lt;br /&gt;svndumptool transform-revprop svn:author originalregexp newvalue repo.dump newrepo.dump&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;or another script:&lt;br /&gt;&lt;div style="background-color: #CCC;"&gt;&lt;br /&gt;http://justatheory.com/computers/vcs/svn/modify_author.html&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-6008858563764410029?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/6008858563764410029/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=6008858563764410029' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/6008858563764410029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/6008858563764410029'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/12/svn-komutlar.html' title='SVN Komutları'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-5904317934607529506</id><published>2010-09-06T05:37:00.000-07:00</published><updated>2010-09-06T05:41:43.070-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><title type='text'>Hibernate Deneyimlerim</title><content type='html'>1. Discriminated Entity yapısında composite id'yi sadece superclass'da uygulayabiliriz. Yoksa aşağıdaki hatayı alırız.&lt;br /&gt;&lt;br /&gt;java.lang.ClassCastException: org.hibernate.mapping.SingleTableSubclass cannot be cast to org.hibernate.mapping.RootClass&lt;br /&gt;&lt;br /&gt;StackOverFlow Thread : http://stackoverflow.com/questions/3615778/can-i-use-compositeid-on-subclasses-of-discriminated-entity-hierarchy&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-5904317934607529506?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/5904317934607529506/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=5904317934607529506' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/5904317934607529506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/5904317934607529506'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/09/hibernate-deneyimlerim.html' title='Hibernate Deneyimlerim'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-477948786306584864</id><published>2010-08-19T00:15:00.000-07:00</published><updated>2010-08-19T00:33:27.731-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='annotation'/><title type='text'>Java ve Annotation'lar</title><content type='html'>Dün karşılaştığım bir olay. User Authentication &amp; Authorization işlemlerini koşturduğum üç aşamalı bir yapım mevcuttu.&lt;br /&gt;&lt;br /&gt;BaseAction (temel işlemler var)&lt;br /&gt;      / \&lt;br /&gt;       |&lt;br /&gt;       |&lt;br /&gt;BuyerBaseAction (sadece sisteme giriş yapıp/yapmadığı kontrolü var)&lt;br /&gt;      / \&lt;br /&gt;       |&lt;br /&gt;       |&lt;br /&gt;SellerBaseAction (login kontrolünden geçecek ve satış yapmak için satıcı özelliğine sahip olması gerekecek)&lt;br /&gt;&lt;br /&gt;Ve bunlardan türeyen bir action sınıfları. Dün öyle bir durum oldu ki bir buyer action içerisindeki method çağırımından önce login kontrolü yapılmaması istendi. Bunun için yöntemim ya bu yordamı alıp üst seviyeye taşıyacaktım, böylelikle hiçbir kontrol yapılmamış olacaktı. Böyle yapınca yeni bir URL, konfigurasyon dosyalarından bir yönlendirme değişklikleri yapmak, ve JSP'lere girip teker teker bu yordamı çağıran bütün URL'leri değiştirmek zorunda kalacaktım.&lt;br /&gt;&lt;br /&gt;Sonra Annotation'lar aklıma geldi. Hemen sadece yordamlar için kullanılabilecek NotLoginRequired isminde bir annotation oluşturdum. çok fazla esnek olmasına gerek yoktu, sadece o kontrolü yapmak istemediğimi belirtsin yeterliydi.&lt;br /&gt;&lt;br /&gt;Ve yardımıma koşan diğer bir yapı ise, Java Reflection's dı. Struts DispatchAction içerisindeki getMethodName() ile çağırılan yordam ismini aldım. Java Reflections kullanarak Method nesnesini elde ettim. Bu nesnenin getAnnotation() yordamını kullanarak dönen değerin null olmasına göre login kontrolünü yap gibi şart koydum. Ve sorun ortadan kalktı.&lt;br /&gt;&lt;br /&gt;&lt;pre class="java" name="code" style="display: none;"&gt;&lt;br /&gt;@Target(ElementType.METHOD)&lt;br /&gt;@Retention(RetentionPolicy.RUNTIME)&lt;br /&gt;public @interface NotLoginRequired {&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="java" name="code" style="display: none;"&gt;&lt;br /&gt;Class clazz = getClass();&lt;br /&gt;&lt;br /&gt;String methodName = getMethodName(mapping, form, request, response, mapping.getParameter());&lt;br /&gt;&lt;br /&gt;Method method = clazz.getMethod(methodName, ActionMapping.class, ActionForm.class, HttpServletRequest.class, HttpServletResponse.class);&lt;br /&gt;&lt;br /&gt;Annotation notLoginRequiredAnnotation = method.getAnnotation(NotLoginRequired.class);&lt;br /&gt;&lt;br /&gt;if(notLoginRequiredAnnotation == null){&lt;br /&gt;&lt;br /&gt;     // do login control&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-477948786306584864?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/477948786306584864/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=477948786306584864' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/477948786306584864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/477948786306584864'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/08/java-ve-annotationlar.html' title='Java ve Annotation&apos;lar'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-1446499176822315180</id><published>2010-08-16T03:27:00.000-07:00</published><updated>2010-08-16T03:59:23.386-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wicket'/><title type='text'>Apache Wicket'da Uluslararasılaştırma</title><content type='html'>&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;" id="internal-source-marker_0.5460820808515532"  &gt;Site diline göre Wicket üç çeşit kaynağı çeşitlendirebilir:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;&lt;/span&gt;&lt;ol&gt;&lt;li   style="list-style-type: decimal; color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;Şekillendirme Dosyaları (Markup Files)&lt;/span&gt;&lt;/li&gt;&lt;li   style="list-style-type: decimal; color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;Lokalleştirme Kaynak Demetleri ve Özellik Dosyaları (Localization Resource Bundles &amp;amp; Properties Files)&lt;/span&gt;&lt;/li&gt;&lt;li   style="list-style-type: decimal; color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;Form giriş kontrolleri ve Özellik Dosyaları  (Form Input Validators &amp;amp; Properties Files)&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;Lokal  (Locale), gelen HTTP isteğindeki USER AGENT alanında tanımlı LOCALE  header’ina bakılarak Wicket WebRequest nesnesi içerisine yüklenir.  İsteğe bağlı olarak Wicket Session nesnesi içerisindeki setLocale()  yordamı kullanılarak oturum süresince bu ifade tutulabilir.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;Çeşitlendirme  lokal ile yapılabileceği gibi, Session içerisindeki setStyle() ile  belirtilen stil’e {ağaç stili, çelik stili, deniz stili v.b.} göre de  yapılabilir.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;&lt;/span&gt;&lt;br /&gt;&lt;h2&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:18pt;"  &gt;Şekillendirme Dosyaları (Markup Files)&lt;/span&gt;&lt;/h2&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;ResourceStreamLoader,  Wicket içerisinde lokal (locale) ve stil (Style) değerlerine göre hangi  Markup File’in yükleneceğini belirler. Öncelikle belirtilen stile ait  dosyayı arar, bulamazsa lokal değerine uygun dosyayı arar, bunu da  bulamazsa varsayılan (default) dosyayı yükler.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;Varsayılan Dosya:&lt;/span&gt;&lt;ul&gt;&lt;li   style="list-style-type: disc; color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;Anasayfa.html&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;Lokalleştirilmiş Dosya:&lt;/span&gt;&lt;ul&gt;&lt;li   style="list-style-type: disc; color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;Anasayfa_tr_TR.html&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;Stillendirilmiş Dosya:&lt;/span&gt;&lt;ul&gt;&lt;li   style="list-style-type: disc; color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;Anasayfa_agac.html&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;ve bunların kombinasyonları: &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;&lt;/span&gt;&lt;ol&gt;&lt;li   style="list-style-type: decimal; color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;[sourcePath]/name[style][locale].[extension]&lt;/span&gt;&lt;/li&gt;&lt;li   style="list-style-type: decimal; color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;[sourcePath]/name[locale].[extension]&lt;/span&gt;&lt;/li&gt;&lt;li   style="list-style-type: decimal; color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;[sourcePath]/name[style].[extension]&lt;/span&gt;&lt;/li&gt;&lt;li   style="list-style-type: decimal; color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;[sourcePath]/name.[extension]&lt;/span&gt;&lt;/li&gt;&lt;li   style="list-style-type: decimal; color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;[classPath]/name[style][locale].[extension]&lt;/span&gt;&lt;/li&gt;&lt;li   style="list-style-type: decimal; color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;[classPath]/name[locale].[extension]&lt;/span&gt;&lt;/li&gt;&lt;li   style="list-style-type: decimal; color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;[classPath]/name[style].[extension]&lt;/span&gt;&lt;/li&gt;&lt;li   style="list-style-type: decimal; color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;[classPath]/name.[extension]&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;&lt;/span&gt;&lt;br /&gt;&lt;h2&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:18pt;"  &gt;Lokalleştirme Kaynak Demetleri (Localized Resource Bundles)&lt;/span&gt;&lt;/h2&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;Uluslararasılaştırılacak  (internationalization) kapsamında uygulama içerisinde bütün ifadeleri  ResourceBundles properties dosyaları üzerinde tutabilir.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;Wicket  içerisinde lokalleştirme özelliğine ait bütün işlemler Localizer sınıfı  içerisinde tanımlanmıştır. Application tarafından paylaştırılan  Localizer sınıfına bütün Component’lerde tanımlı getLocalizer() yordamı  ile erişilebilir. Tanımlı olan bütün resourcebundle dosyaları  AbstractStringResourceLoader sınıfından türemiş alt sınıflar tarafından  yönetilir. Application üzerinden ComponentStringResourceLoader ve  ApplicationStringResourceLoader nesneleri sağlanır. &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;İlgili  Component için Application tarafından verilen listeden ilgili  ComponentStringResourceLoader  bulunur, eğer burada istenen anahtar  (key) yoksa sınıf hiyerarşisine göre ilgili  ComponentStringResourceLoader’lara bakılır. Eğer bunlarda da yoksa en  son ApplicationStringResourceLoader’a bakılır. &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;Eğer  Page’e eklenmemiş bir Component için Localizer kullanılıyorsa, Wicket  tarafında hata fırlatılır. Bunu önlemek için, Component eklenene kadar,  StringResourceModel kullanımı daha faydalı olacaktır.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;ResourceBundle properties dosyasının ismi ile ilgili Component’in sınıf ismi iaynı olmak zorundadır.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0); font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;"  &gt;StringResourceModel kullanımına örnek : &lt;/span&gt;&lt;br /&gt;&lt;pre style="display: none;" name="code" class="java"&gt;&lt;br /&gt;StringResourceModel kullanımına örnek :&lt;br /&gt;&lt;br /&gt;public MyPage extends WebPage&lt;br /&gt;{&lt;br /&gt;public MyPage(final PageParameters parameters)&lt;br /&gt;{&lt;br /&gt;WeatherStation ws = new WeatherStation();&lt;br /&gt;Model model = new Model(ws);&lt;br /&gt;add(new Label("weatherMessage",&lt;br /&gt;         new StringResourceModel(&lt;br /&gt;             "weather.detail", this, model,&lt;br /&gt;             new Object[]&lt;br /&gt;             {&lt;br /&gt;                 new Date(),&lt;br /&gt;                 new PropertyModel(model, "currentStatus"),&lt;br /&gt;                 new PropertyModel(model, "currentTemperature"),&lt;br /&gt;                 new PropertyModel(model, "units")&lt;br /&gt;             }));&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;/span&gt;ve MyPage_en.properties dosyası :&lt;/span&gt;&lt;br /&gt;&lt;pre style="display: none;" name="code" class="java"&gt;&lt;br /&gt;weather.detail=The report for {0,date}, shows the temparature as {2,number,###.##} {3} and the weather to be {1}&lt;/pre&gt;&lt;span style="font-style: normal; text-decoration: none; vertical-align: baseline;font-family:Arial;font-size:11pt;color:transparent;" id="internal-source-marker_0.5460820808515532"   &gt;Burada  StringResourceModel, içerisinde Localizer kullanmaktadır ve Localizer  içerisindeki tüm fonksiyonliteyi sağlamaktadır. Tek farkı wicket bileşen  hiyerarşisi işlenmeden çalıştırılmaması ve böyle hata fırlamanın  gerçekleşmemesidir.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Kaynak : &lt;a href="https://cwiki.apache.org/WICKET/localization-and-skinning-of-applications.html"&gt;https://cwiki.apache.org/WICKET/localization-and-skinning-of-applications.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-1446499176822315180?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/1446499176822315180/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=1446499176822315180' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/1446499176822315180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/1446499176822315180'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/08/apache-wicketda-uluslararaslastrma.html' title='Apache Wicket&apos;da Uluslararasılaştırma'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-5529994956549314608</id><published>2010-08-13T03:28:00.000-07:00</published><updated>2010-08-13T04:44:09.227-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wicket'/><title type='text'>Koşula bağlı olarak Wicket Bileşeni göstermek</title><content type='html'>Wicket, bileşen tabanlı (component based) bir web çatısıdır. kullanıcı arayüzüne (User Interface) hareketlilik Java kodları ile verilmektedir. Yanlız arayüzdeki bileşenleri yerleşimi ve görünümleri ise yazılan wicket sınıfları ile aynı paket yapısında ve aynı isimde olan HTML dosyaları sağlanmaktadır. HTML dosyası içerisindeki bileşenler wicket:id tanımlayıcısı ekleyerek, Wicket kodları içerisinden bu tanımlayıcıya bileşen eklenilir. Burada wicket çok katı olup, wicket:id ile tanımlanmış bir bileşene Java tarafında bir bileşen nesnesi eklemek zorunluluğu kılar. Gelelim asıl soruna. Bu zorunluluktan dolayı bir duruma bağlı olarak bileşenin kullanıcı arayüzünde görünmesini istemezsem ne olacak? Tabii ki çözüm bileşen eklememek olamaz yoksa Wicket hata verir. &lt;br /&gt;&lt;br /&gt;1. Çözüm : boş bir panel eklemek olacaktır.&lt;br /&gt;2. Çözüm : Wicket tarafında bileşenleri isVisibility() yordamları ezilerek görünüp görünmemesi sağlanır.&lt;br /&gt;&lt;br /&gt;&lt;pre class="html" name="code" style="display: none;"&gt;&lt;br /&gt;&amp;lt;div class="price-box" wicket:id="my-web-markup-container"&amp;gt;&lt;br /&gt;  &amp;lt;span wicket:id="price" style="border:1px solid #ff0"&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="java" name="code" style="display: none;"&gt;&lt;br /&gt;WebMarkupContainer wmc = new WebMarkupContainer("my-web-markup-container") {&lt;br /&gt;  public boolean isVisible() {&lt;br /&gt;    return hasPrice();&lt;br /&gt;  }&lt;br /&gt;};&lt;br /&gt;wmc.add(new Label("price", priceModel));&lt;br /&gt;add(wmc);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;3. Çözüm : Wicket 1.3 ile gelen wicket:enclosure tanımını kullanmak. Enclosure ile tanımlanan barındırıcı, içerisindeki bileşenlerin visibility durumuna bakarak gösterimi yönetmektedir.&lt;br /&gt;&lt;pre class="java" name="code" style="display: none;"&gt;&lt;br /&gt;Label price = new Label("price", priceModel) {&lt;br /&gt;  public boolean isVisible() {&lt;br /&gt;    return hasPrice();&lt;br /&gt;  }&lt;br /&gt;};&lt;br /&gt;add(price);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="html" name="code" style="display: none;"&gt;&lt;br /&gt;&amp;lt;wicket:enclosure&amp;gt;&lt;br /&gt;&amp;lt;div class="price-box"&amp;gt;&lt;br /&gt;  &lt;span wicket:id="price" style="border:1px solid #ff0"&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/wicket:enclosure&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Eğer enclosure barındırıcı birden fazla bileşen içeriyorsa bunlardan birinin durumuna göre gösterimi yönetebilmektedir.&lt;br /&gt;&lt;pre class="html" name="code" style="display: none;"&gt;&lt;br /&gt;&amp;lt;wicket:enclosure child="price"&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;/wicket:enclosure&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Kaynaklar : &lt;br /&gt;&lt;a href="http://www.systemmobile.com/?page_id=253"&gt;http://www.systemmobile.com/?page_id=253&lt;/a&gt;&lt;br /&gt;&lt;a href="http://alessandroribeiro.com/?q=en/node/57"&gt;http://alessandroribeiro.com/?q=en/node/57&lt;/a&gt;&lt;br /&gt;&lt;a href="http://stackoverflow.com/questions/1242105/wicket-conditional-display-in-template"&gt;http://stackoverflow.com/questions/1242105/wicket-conditional-display-in-template&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-5529994956549314608?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/5529994956549314608/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=5529994956549314608' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/5529994956549314608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/5529994956549314608'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/08/kosula-bagl-olarak-wicket-bileseni.html' title='Koşula bağlı olarak Wicket Bileşeni göstermek'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-4906345251581366008</id><published>2010-08-12T23:58:00.000-07:00</published><updated>2010-08-13T00:06:39.325-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rdesktop'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>RDESKTOP ile Windows işletim sistemlerine uzaktan erişim</title><content type='html'>RDESKTOP ile XP bilgisayarıma uzaktan erişebiliyorum. Tamamiyle linux üzerinde çalışmak için güzel bir imkan sağlıyor bana.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;rdesktop -f IP/HOSTNAME&lt;/span&gt; komutu ile fullscreen bağlanabiliyorum. &lt;span style="font-weight:bold;"&gt;CTRL+ALT+ENTER&lt;/span&gt; ile fullscreen moda giriş yapıp çıkabiliyorum.&lt;br /&gt;&lt;br /&gt;Arada color depth uyuşmazlığından dolayı rdesktop kapanabiliyor. Bunun için XP'de run'a "gpedit.msc" yazıp gelen yönetim ekranında Computer &lt;span style="font-weight:bold;"&gt;Configuration/Administrative Templates/Terminal Services&lt;/span&gt; de &lt;span style="font-weight:bold;"&gt;"limit maximum color depth"&lt;/span&gt; seçip color depth olarak uygun derinliği seçmemiz gerek.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-4906345251581366008?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/4906345251581366008/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=4906345251581366008' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/4906345251581366008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/4906345251581366008'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/08/rdesktop-ile-windows-isletim.html' title='RDESKTOP ile Windows işletim sistemlerine uzaktan erişim'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-7316475265145482105</id><published>2010-07-15T01:11:00.000-07:00</published><updated>2010-07-15T01:17:20.478-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='db2'/><title type='text'>DB2 Komutlarım</title><content type='html'>1. AutoGenerated Primary Key'in NextId değerini değiştirmek&lt;br /&gt;&lt;br /&gt;ALTER TABLE SM_SELLER_BUYER ALTER ID RESTART WITH 9013470&lt;br /&gt;&lt;br /&gt;2. Sequence'in sonraki değerini öğrenmek&lt;br /&gt;&lt;br /&gt;select seq.*&lt;br /&gt;from sysibm.syscolumns as c,sysibm.sysdependencies as d&lt;br /&gt;    ,sysibm.syssequences as s ,syscat.SEQUENCES as seq&lt;br /&gt;where c.tbcreator = d.dschema and c.tbname = d.dname &lt;br /&gt;    and d.bname = s.seqname and d.bschema = s.seqschema &lt;br /&gt;    and seq.SEQID=s.SEQID&lt;br /&gt;    and c.identity = 'Y' and d.dtype = 'T' and d.btype ='Q' and s.seqtype = 'I'&lt;br /&gt;    and c.tbname='TABLE_NAME' and c.tbcreator='USERNAME';&lt;br /&gt;&lt;br /&gt;3. db2 drop db &lt;DBNAME&gt;&lt;br /&gt;4. db2 connect to &lt;DBNAME&gt; user &lt;USERNAME&gt;&lt;br /&gt;5. db2 get db cfg &lt;DBNAME&gt;&lt;br /&gt;6. db2 restore db &lt;DBNAME&gt; from &lt;PATH&gt; without prompting&lt;br /&gt;7. db2 catalog tcpip node &lt;NODENAME&gt; remote &lt;HOSTNAME/IP&gt; server &lt;DB2PORT&gt;&lt;br /&gt;8. db2 catalog db &lt;DBNAME&gt; at node &lt;NODENAME&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-7316475265145482105?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/7316475265145482105/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=7316475265145482105' title='1 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/7316475265145482105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/7316475265145482105'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/07/db2-komutlarm.html' title='DB2 Komutlarım'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-5324826606033793935</id><published>2010-07-09T06:21:00.000-07:00</published><updated>2010-07-09T06:28:20.712-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><title type='text'>EXCEPTION : Repeated column in mapping for entity: ... (should be mapped with insert="false" update="false")</title><content type='html'>&lt;span style="font-weight:bold;"&gt;"Repeated column in mapping for entity: ... (should be mapped with insert="false" update="false")"&lt;/span&gt; hatasını aldığımız zaman yapacağımız ilk şey ilgili entity ve süper entity'de aynı JoinColumn üzerinden iki farklı mapping'in yapılıp yapılmadığını kontrol etmektir. Eğer iki mapping'in tanımlı olduğu property'lere atama yaparsak hibernate tek join column için hangi entity'nin id'sini kullanacağını bilemeyecektir. Çözüm ikinci bir join column oluşturmak olacaktır.&lt;br /&gt;&lt;br /&gt;Bu hataya neden olan tanımlamalar:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@Entity&lt;br /&gt;public class Comment {&lt;br /&gt;&lt;br /&gt;@ManyToOne&lt;br /&gt; @JoinColumn(name="&lt;span style="font-weight:bold;"&gt;ENTITY_ID&lt;/span&gt;", referencedColumnName="ID")&lt;br /&gt;private Comment parentComment;&lt;br /&gt;&lt;br /&gt;@ManyToOne&lt;br /&gt; @JoinColumn(name="&lt;span style="font-weight:bold;"&gt;ENTITY_ID&lt;/span&gt;", referencedColumnName="ID")&lt;br /&gt;private Article article;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Comment tablosuna PARENT_ID sutunu ekleyelim ve yeni kodumuz:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@Entity&lt;br /&gt;public class Comment {&lt;br /&gt;&lt;br /&gt;@ManyToOne&lt;br /&gt; @JoinColumn(name="&lt;span style="font-weight:bold;"&gt;PARENT_ID&lt;/span&gt;", referencedColumnName="ID")&lt;br /&gt;private Comment parentComment;&lt;br /&gt;&lt;br /&gt;@ManyToOne&lt;br /&gt; @JoinColumn(name="&lt;span style="font-weight:bold;"&gt;ENTITY_ID&lt;/span&gt;", referencedColumnName="ID")&lt;br /&gt;private Article article;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-5324826606033793935?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/5324826606033793935/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=5324826606033793935' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/5324826606033793935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/5324826606033793935'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/07/exception-repeated-column-in-mapping.html' title='EXCEPTION : Repeated column in mapping for entity: ... (should be mapped with insert=&quot;false&quot; update=&quot;false&quot;)'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-7968873105289940090</id><published>2010-07-08T07:33:00.000-07:00</published><updated>2010-07-11T23:35:18.641-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><title type='text'>Annotation ile Hibernate Any Kullanımı</title><content type='html'>Bazen sistem içerisinde bazı tablolara ait logları tek bir tablo üzerinde tutmak ihtiyacı duyarız. Log tablosunun temel iki sütunu &amp;lt;&amp;lt;RECORD_ID&amp;gt;&amp;gt;,&amp;lt;&amp;lt;RECORD_TYPE&amp;gt;&amp;gt; olacaktır. &amp;lt;&amp;lt;RECORD_TYPE&amp;gt;&amp;gt; bazen açık sınıf ismi veya kısaltma olabilir. Bu durumda bunların entity sınıflarını oluşturmak istediğimizde ilişkiyi nasıl tanımlayacağız?&lt;br /&gt;&lt;br /&gt;Bunu @any annotation'ları ile gerçekleştirececeğiz:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@Entity&lt;br /&gt;@Table(name = "LOG")&lt;br /&gt;public class LOG{&lt;br /&gt;&lt;br /&gt;    @Id&lt;br /&gt;    @GeneratedValue&lt;br /&gt;    private Long id;&lt;br /&gt;&lt;br /&gt;    @Any(metaColumn = @Column(name = "RECORD_TYPE"))&lt;br /&gt;    @AnyMetaDef(idType = "long", metaType = "string", &lt;br /&gt;            metaValues = { &lt;br /&gt;             @MetaValue(targetEntity = ARTICLE.class, value = "A"),&lt;br /&gt;             @MetaValue(targetEntity = COMMENT.class, value = "C"),&lt;br /&gt;             @MetaValue(targetEntity = IMAGE.class, value = "I")&lt;br /&gt;       })&lt;br /&gt;    @JoinColumn(name="RECORD_ID")&lt;br /&gt;    private Object item;&lt;br /&gt;&lt;br /&gt;     .......&lt;br /&gt;    public Object getItem() {&lt;br /&gt;        return item;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setItem(Object item) {&lt;br /&gt;        this.item = item;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Entity'leri liste olarak almak istiyorsak @ManyToAny annotation'ını kullanmalıyız. Bunun için ilişkileri tutacak LOG_RECORDS isimli ara tabloya ihtiyacımız olacaktır.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@ManyToAny(&lt;br /&gt;metaColumn = @Column( name = "RECORD_TYPE" ) )&lt;br /&gt;@AnyMetaDef(idType = "long", metaType = "string", &lt;br /&gt;      metaValues = { &lt;br /&gt;         @MetaValue(targetEntity = ARTICLE.class, value = "A"),&lt;br /&gt;         @MetaValue(targetEntity = COMMENT.class, value = "C"),&lt;br /&gt;         @MetaValue(targetEntity = IMAGE.class, value = "I")&lt;br /&gt;  })&lt;br /&gt;@Cascade( { org.hibernate.annotations.CascadeType.ALL } )&lt;br /&gt;@JoinTable( name = "LOG_RECORDS", joinColumns = @JoinColumn( name = "LOG_ID" ),&lt;br /&gt;    inverseJoinColumns = @JoinColumn( name = "RECORD_ID" ) )&lt;br /&gt;public List&lt;Property&gt; getGeneralProperties() {&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Bu mapping'in tersinin nasıl yapıldığını bulamadım. Mantık olarak sanırım bu tanımlama tek taraflı bir ilişkiyi içeriyor. Bu yüzden üzerinde çalıştığım veritabanı şemasını yeniden gözden geçirip düzenledim. Sınıf hiyerarşisindeki her entity için tek tablo yapısını kullanmaya karar verdim. BKZ : &lt;a href="http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#d0e1168"&gt;Hibernate Inheritance&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-7968873105289940090?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/7968873105289940090/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=7968873105289940090' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/7968873105289940090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/7968873105289940090'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/07/annotation-ile-hibernate-any-kullanm.html' title='Annotation ile Hibernate Any Kullanımı'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-6518586714042246960</id><published>2010-07-02T07:20:00.000-07:00</published><updated>2010-07-02T07:27:39.906-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='canon eos 500d'/><category scheme='http://www.blogger.com/atom/ns#' term='gökova'/><category scheme='http://www.blogger.com/atom/ns#' term='scuba diving'/><category scheme='http://www.blogger.com/atom/ns#' term='istanbul'/><category scheme='http://www.blogger.com/atom/ns#' term='kiteboard'/><category scheme='http://www.blogger.com/atom/ns#' term='bodrum'/><title type='text'>İstanbul'a Geçici Süreliğine Elveda</title><content type='html'>Bu akşam tatile çıkıyorum. yoğun bir kış döneminden sonra deniz, güneş, kum hep bir arada güzel bir tatil olacak. Peki ne yapacağım?&lt;br /&gt;&lt;br /&gt;Bodrum'da Cumartesi ve Pazar dalış yapacağım. Pazar akşamı Gökova Akyazı'ya geçeceğim. Orada çadır alanı bulunup çadırımı kuracağım. Pazartesi sabahı KiteBoard alanına gidip 3 günlük sıkı bir kiteboard eğitiminden geçeceğim. bu arada yanımda Canon EOS 500D, EF-S 18-55 IS Kit Lens ve Sigma 70-300mm F4-5.6 APO DG Macro lensimde olacak. Kiteboard yapanları ve oradaki doğal hayatı fotoğraflayacağım. Duyduğuma göre kuş çeşidi bolmuş ve 70-300mm Macro lensimi test etmek için güzel bir ortam olacak. Oranın keyfini çıkarınca belki Datça taraflarına geçerim. Sonra Pazar dönüş ve yine aynı iş temposuna devam. &lt;br /&gt;&lt;br /&gt;İstanbul elveda... :D :D :D Senden bir kurtulabilsem, ama biliyorum ki kurtulduğum zaman da seni özleyeceğim :( :( :(&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-6518586714042246960?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/6518586714042246960/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=6518586714042246960' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/6518586714042246960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/6518586714042246960'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/07/istanbula-gecici-sureligine-elveda.html' title='İstanbul&apos;a Geçici Süreliğine Elveda'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-8785059561658784557</id><published>2010-05-31T01:13:00.000-07:00</published><updated>2010-06-02T00:53:31.009-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CVS'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Mylyn'/><category scheme='http://www.blogger.com/atom/ns#' term='JIRA'/><title type='text'>Bildirim ve Versiyon Yönetim Sistemleri ile Hızlı Uygulama Geliştirme</title><content type='html'>Uygulama geliştirme ortamlarının vazgeçilmezi Versiyonlama Yönetim Sistemleri (Code Versioning Systems) ve Bildirim Takip Sistemleri (Issue Tracking Systems)... Bildirim takip sistemlerinde yeni açılan her bir bildirim için tekil bir id tanımlanmaktadır. Kod değişikliklerini versiyonlama sistemine atarkende her zaman bizden bir yorum girmemizi ister kullandığımız arayüz. Çoğu zaman bu yorumlar önemsenmez ve boş bırakılır. Yorum olarak bildirim takip sistemindeki bildirim id'si ve bildirim başlığı alınıp yorum içerisine eklenirse kabul görmüş bildirimlerin TRUNK'a aktarılması daha kolay olabilmektedir. Kode Versiyonlama Sistemi ve JIRA'yı Eclipse üzerinde entegre hale getirip kod aktarımlarımızı nasıl kolay hale getireceğiz görelim.&lt;br&gt;&lt;br&gt;&lt;h2&gt;ECLIPSE &amp;amp; JIRA &amp;amp; MYLYN Üçlüsü&lt;/h2&gt;&lt;br&gt;Eclipse platformunda &lt;b&gt;Window--&amp;gt;Show View--&amp;gt;Other--&amp;gt;Mylyn&lt;/b&gt; altındaki View’leri seçerek aktif Persfektif’te görünmeleri sağlanır.&lt;br&gt;&lt;br&gt;&lt;div id="jqra" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_59ddgckfd4_b" style="height: 239px; width: 276px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;Mylyn’i JIRA ile ilişkilendirmek için &lt;b&gt;Task Repositories (View)--&amp;gt;Add Task Repository&lt;/b&gt; penceresini açmalıyız. Açılan pencerede&lt;br&gt;&lt;br&gt;&lt;div id="qp3g" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_60fs4kjbg5_b" style="height: 278px; width: 349px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;JIRA connector’ü görünmüyorsa biraz işimiz var demektir. JIRA connector’unu kurmamız gerekli. &amp;lt;font style="font-weight: bold;"&amp;gt;Help--&amp;gt;Software Updates--&amp;gt;Find And Install&amp;lt;/font&amp;gt; ekranından Search for new features to install seçeneği seçilip gelen listeden&lt;b&gt; Mylyn&lt;/b&gt; ve &lt;b&gt;Mylyn Extras&lt;/b&gt; aktif hale getirilir.&lt;br&gt;&lt;br&gt;&lt;div id="k4_2" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_61qtcqh8cz_b" style="height: 559px; width: 600px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;Finish düğmesine bastığımızda&lt;br&gt;&lt;div id="ck1l" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_62hbwsxmd7_b" style="height: 651px; width: 547px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;Burada birbiri ile bağlantılı seçimler mevcuttur. Seçimleri yukarıdaki gibi yapıp Next düğmesine basalım. Sözleşmeyi onayladıktan sonra seçimleri indirmeye başlayalım.&lt;br&gt;&lt;br&gt;Kurulum sonrası “Add Task Repository” penceresinin yeni hali :D&lt;br&gt;&lt;br&gt;&lt;div id="xkwa" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_63c7gxs3gn_b" style="height: 275px; width: 418px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;JIRA’yı seçelim ve yolumuza devam edelim. Yeni pencerede sunucu ayarlarını yapalım:&lt;br&gt;&lt;br&gt;&lt;div id="nbb0" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_64cf79nf7w_b" style="height: 438px; width: 408px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;h2&gt;Bildirim Sorgularının Oluşturulması&lt;/h2&gt;&lt;br&gt;Bildirim sorgularını oluşturmayı &lt;b&gt;Task List&lt;/b&gt; ve &lt;b&gt;Task Repositories&lt;/b&gt; pencelerinde Context Menu’den New Query penceresinden yapabiliriz.&lt;br&gt;&lt;br&gt;&lt;div id="u21m" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_65mp7fwphx_b" style="height: 415px; width: 438px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;Burada JIRA sunucusunda oluşturulmuş sorguları kullanabileceğimiz gibi Eclipse tarafında da kendimize ait sorgular oluşturabiliriz.&lt;br&gt;&lt;br&gt;İlk seçeneği seçelim. Aşağıdaki gibi bir ekran gelecektir. Burada JIRA üzerinde tanımlı tüm yapılar ve özellikler listelenmektedir.&lt;br&gt;&lt;br&gt;&lt;div id="jo9-" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_66fmncrcc6_b" style="height: 664.179px; width: 648px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;h2&gt;Eclipse ve Mylyn Kullanımı&lt;/h2&gt;&lt;br&gt;Bildirimlerimizi en iyi şekilde yönetecek şekilde sorgularımızı oluşturduktan sonra gelelim Mylyn kullanımını görelim. “Task List”penceresini kullanarak üzerinde çalışma yapacağımız bildirimi seçeriz. Seçili bildirimin Context Menu’sunde bulunan &lt;b&gt;Activate &lt;/b&gt;seçeneğini kullarak Mylyn Context’i için aktif hale getiririz.&lt;br&gt;&lt;br&gt;Bir bildirimi aktif yaptığımızda “Package Explorer” ekranında aktif bildirim için üzerinde çalışılan ve açılan dosyalar listelenir. Bir bildirim aktif haldeyken herhangi bir dosya açıldığında bu dosya bildirimin Mylyn Context’ine eklenir. Eğer tüm dosyaları listelemek istiyorsak sağ üst köşedeki&amp;nbsp;&amp;nbsp;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_67gnpzmggp_b" style="float: left; height: 31px; margin-left: 1em; margin-right: 0pt; width: 31px;"&gt;&amp;nbsp; (Focus on Active Tast) düğmesini pasif yapmamız yeterlidir.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div id="hmt:" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_68gg5zssfj_b" style="height: 347px; width: 340px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&amp;nbsp;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_67gnpzmggp_b" style="float: left; height: 31px; margin-left: 1em; margin-right: 0pt; width: 31px;"&gt;&amp;nbsp; (Focus on Active Tast) düğmesi aktif durumd&amp;nbsp;&amp;nbsp; (Focus on Active Tast) düğmesi aktif durumdayken bir dosyayı bulmak istiyorsak CTRL+ SHIFT+R tuş kombinasyonu kullanabiliriz. Yada herhangi bir klasöre (ALT + Mouse Left Button) kombinasyonu ile tıkladığımızda o klasör altındakiler dosya seçimi yapana kadar listenir.&lt;br&gt;&lt;br&gt;&lt;div id="wmc4" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_69g3r23wdx_b" style="height: 265.446px; width: 648px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;Task List ekranında aktif olan ve daha önce aktif olmuş bildirimleri yukarıdaki resimde işaretli olan kısımdan görebiliriz.&lt;br&gt;&lt;br&gt;&lt;h2&gt;Mylyn ve CVS Commit İşlemi&lt;/h2&gt;&lt;br&gt;Bir bildirim üzerinde çalışmaya başlamadan önce:&lt;br&gt;&lt;br&gt;1.&amp;nbsp;&amp;nbsp; &amp;nbsp;Bildirim Aktif duruma getirilir.&lt;br&gt;2.&amp;nbsp;&amp;nbsp; &amp;nbsp;Bildirim Eclipse Editör ekranında açılır.&lt;br&gt;3.&amp;nbsp;&amp;nbsp; &amp;nbsp;Kendimize assign edilmemişse kendi üzerimize alırız.&lt;br&gt;4.&amp;nbsp;&amp;nbsp; &amp;nbsp;Bildirimi “Start Progress” durumuna getiririz&lt;br&gt;5.&amp;nbsp;&amp;nbsp; &amp;nbsp;Dosyalar üzerinde gerekli değişiklikleri yaparız.&lt;br&gt;6.&amp;nbsp;&amp;nbsp; &amp;nbsp;İşimiz bittikten sonra bildirimi “Stop Progress” durumuna getiririz.&lt;br&gt;7.&amp;nbsp;&amp;nbsp; &amp;nbsp;Kendi testlerimizi yaptıktan sonra “Resolve Issue” durumuna getiririz.&lt;br&gt;8.&amp;nbsp;&amp;nbsp; &amp;nbsp;CVS Commit’lerimizi gerçekleştiririz.&lt;br&gt;9.&amp;nbsp;&amp;nbsp; &amp;nbsp;Müşteri Test’ine deploy işleminden sonra ilgili bildirimi “In Test” durumuna getiririz.&lt;br&gt;10.&amp;nbsp;&amp;nbsp; &amp;nbsp;Başka bir bildirim için çalışılan bildirimi pasif duruma getiririz.&lt;br&gt;&lt;br&gt;&lt;div id="w6wt" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_71z35kj3ft_b" style="height: 884.204px; width: 648px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;div style="text-align: center;"&gt;2. ve 3. işlemler için ekran görüntüsü&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;&lt;div id="v9x0" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_72fn7pcthq_b" style="height: 499.652px; width: 648px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;div style="text-align: center;"&gt;8. adım için ekran görüntüsü&lt;br&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;Görüldüğü gibi CO-368&amp;nbsp; ve bildirim açıklaması commit mesajı olarak otomatik eklenmektedir.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;h2&gt;Bildirim Editör Ekranı&lt;/h2&gt;&lt;br&gt;&lt;div id="hz5c" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_73htj7c3ss_b" style="height: 379.427px; width: 648px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;Sağ üstte işaretli olan bölgedeki actionlar :&lt;br&gt;&lt;div id="l-5n" style="text-align: left;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_74hqcf7kcp_b" style="height: 24px; width: 23px;"&gt; ilgili bildirime ait alt bildirim açmak için kullanılır&lt;br&gt;&lt;/div&gt;&lt;div id="oi:a" style="text-align: left;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_75wdsrqxgc_b" style="height: 26px; width: 26px;"&gt; bildirim değişim seceresini gösterir. Bunun için Eclipse Web Browser’inda “JIRA Change History” sayfasını açar.&lt;br&gt;&lt;/div&gt;&lt;div id="e:.u" style="text-align: left;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_76jstffsf7_b" style="height: 24px; width: 23px;"&gt; bildirime ait JIRA Sayfasını Eclipse Web Browser’inda açar.&lt;br&gt;&lt;br&gt;&lt;/div&gt;&lt;div id="mr7d" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_83z2ccwjcv_b" style="height: 449.247px; width: 648px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;div id="ymb-" style="text-align: left;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_78gks46vhc_b" style="height: 31px; width: 31px;"&gt; bildirimin Aktif / Pasif olmasını yönetir.&lt;br&gt;&lt;/div&gt;&lt;br&gt;&lt;h2&gt;Mylyn Context Yönetimi&lt;/h2&gt;&lt;br&gt;Bir issue aktif durumdayken arama (CTRL + SHIFT +R) yöntemiyle editör de açılan bir dosyayı Package Explorer ‘da göstermektedir. Eğer açılan dosyada bir değişiklik yapılmazsa editör kapatıldığında ilgili dosyayı Mylyn Context ‘ten çıkarır.&lt;br&gt;&lt;br&gt;Eğer bir dosyanın ilgili bildirim Context’inde tanımlı olmasını istiyorsak bunu koyu yazılı duruma getirmeliyiz. Bunun için ilgili dosya için içerik menusunden “Mark as Landmark” komutunu uygulamalıyız.&lt;br&gt;&lt;br&gt;&lt;div id="r-yh" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_80dxzrfhcx_b" style="height: 519px; width: 529px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;h2&gt;Çalışılan Dosyaların Diğer Developer’lar Tarafından Görülmesi&lt;/h2&gt;&lt;br&gt;İlgili bildirime ait editör ekranını açtığımızda Context sekmesini seçerek ilgili dosyaların JIRA bildirimine eklenmesi, bildirimden alınması, başka bir bildirime kopyalanması gibi işlemleri yapabiliriz.&lt;br&gt;&lt;br&gt;&lt;div id="d72_" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_81cmkkf5gv_b" style="height: 509px; width: 601px;"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;“Attach Context”&lt;/b&gt; işlemini yaptıktan sonra JIRA sekmesine geçtiğimizde &lt;b&gt;attachments &lt;/b&gt;bölümüne context paylaşım dosyası eklenmiştir.&lt;br&gt;&lt;br&gt;&lt;div id="zt.p" style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_82hsbhr9fd_b" style="height: 505px; width: 593px;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-8785059561658784557?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/8785059561658784557/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=8785059561658784557' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/8785059561658784557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/8785059561658784557'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/05/bildirim-ve-versiyon-yonetim-sistemleri.html' title='Bildirim ve Versiyon Yönetim Sistemleri ile Hızlı Uygulama Geliştirme'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-1468691101196729952</id><published>2010-05-20T04:58:00.000-07:00</published><updated>2010-05-20T05:07:16.634-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ie'/><category scheme='http://www.blogger.com/atom/ns#' term='flex 4'/><category scheme='http://www.blogger.com/atom/ns#' term='cache'/><title type='text'>Flex HttpService, Browser Cache ve IE</title><content type='html'>Problem :  Özellikle IE içerisinde FLEX HttpService kullanılarak yapılan istek, bir sonraki yüklemelerde yapılmamaktadır. İstek sonucu browser cache'nden geliyor.&lt;br /&gt;&lt;br /&gt;Sebeb : IE, aynı URL'den yapılan GET isteklerini cache'lemektedir. Flex içerisinden HttpService ile yapılan GET isteği de bu nedenden dolayı ilk sonucu getirmektedir.&lt;br /&gt;&lt;br /&gt;Çözüm :&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="color: rgb(0, 0, 0);"&gt; &lt;p&gt;&lt;b&gt;Server side solution:&lt;/b&gt;  Set the HTTP headers of the response to avoid  returning response from cache.&lt;/p&gt; &lt;p&gt;In HTML: (in the header)&lt;/p&gt; &lt;p&gt;&amp;lt;meta equiv="”Cache-Control”" content="”no-cache”"&amp;gt;&lt;br /&gt;&amp;lt;meta equiv="”expires”" content="”0″"&amp;gt;&lt;/p&gt; &lt;p&gt;In PHP: (in the script)&lt;/p&gt; &lt;p&gt;header(”Cache-Control: no-cache, must-revalidate”);&lt;br /&gt;header(”Expires: Mon,  26 Jul 1997 05:00:00 GMT”);&lt;/p&gt; &lt;p&gt;In JSP: (before writing to the output stream)&lt;/p&gt; &lt;p&gt;response.setHeader(”Cache-Control”,”no-cache”);&lt;br /&gt;response.setDateHeader  (”Expires”, 0);&lt;/p&gt; &lt;p&gt;&lt;b&gt;Client side solution:&lt;/b&gt; (1) Make HTTP POST call — only HTTP GET calls  are served from cache or (2) Make sure the HTTP GET URL is different every  time.&lt;/p&gt; &lt;p&gt;(1) Make HTTP POST call –&lt;br /&gt;set method=”POST” and handle the call  appropriately&lt;/p&gt; &lt;p&gt;(2) Append a unique parameter to the HTTP GET call so that the URL is  different every time. A unique time stamp is a good choice.&lt;br /&gt;The following  sample code, may do the job:&lt;/p&gt; &lt;p&gt;var timeStampForNocache:Date = new Date() ;&lt;br /&gt;params.noCacheControlVar =  timeStampForNocache.getTime().toString() ;&lt;br /&gt;I have named the parameter  “noCacheControlVar”. You can name it anything else you please. The name does not  matter. What matters is that the timestamp makes the HTTP GET URL  unique.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Kaynak :  http://shanky.org/2008/08/02/flex-httpservice-browser-cache-and-ie/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-1468691101196729952?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/1468691101196729952/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=1468691101196729952' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/1468691101196729952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/1468691101196729952'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/05/flex-httpservice-browser-cache-ve-ie.html' title='Flex HttpService, Browser Cache ve IE'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-5812267894784327167</id><published>2010-05-06T00:03:00.000-07:00</published><updated>2010-05-06T00:04:46.685-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flash builder'/><category scheme='http://www.blogger.com/atom/ns#' term='flex 4'/><title type='text'>Flash Builder 4 "Could not resolve  to a component implementation." hatası</title><content type='html'>türkçe ortamlarda flashbuilder kurulumu yapıldığında fx:script tanımlarında "Could not resolve &lt;fx:script&gt; to a component implementation." hatası veriyor. bunu çözmek için eclipse.ini dosyasına "-Duser.language=en" ve "-Duser.location =us" tanımlarını eklememiz gerekmektedir.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-5812267894784327167?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/5812267894784327167/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=5812267894784327167' title='1 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/5812267894784327167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/5812267894784327167'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/05/flash-builder-4-could-not-resolve-to.html' title='Flash Builder 4 &quot;Could not resolve &lt;fx:script&gt; to a component implementation.&quot; hatası'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-4828580932865944626</id><published>2010-03-26T05:01:00.000-07:00</published><updated>2011-07-27T04:56:43.913-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Ubuntu ile Uygulama Geliştirme Ortamı oluşturalım</title><content type='html'>Ubuntu işletim sistemine ait son sürümü &lt;a href="http://www.ubuntu.com/GetUbuntu/download"&gt;buradan&lt;/a&gt; indirebilirsiniz. DVD'ye kaydettikten sonra Ubuntu'yu kuralım. Swap ve EXT dosyas sistemine ait partitionları ayırdıktan sonra kurulumu gerçekleştirelim.&lt;br /&gt;&lt;br /&gt;Default ayarlarla kurulumu gerçekleştirirseniz eğer sistemimizde Apache, PHP ve MySql kurulu olmuyor. İlk önce bu kurulumları yapalım ki Joomla, WordPress v.b. kendi blog veya sitemizi gerçekleştirebiliriz.&lt;br /&gt;&lt;br /&gt;1. apt-get repository'lerini güncelleyelim&lt;br /&gt;&lt;br /&gt;&gt;apt-get update&lt;br /&gt;&lt;br /&gt;2. Apache 2 kurulumunu yapalım&lt;br /&gt;&lt;br /&gt;&gt;apt-get install apache2&lt;br /&gt;&lt;br /&gt;/etc/apache2 altına kurulumu gerçekleştiriyor ve "service apache2 start/stop/restart" komutu ile apache'yi yönetebiliriz.&lt;br /&gt;&lt;br /&gt;3. PHP kurulumunu yapalım&lt;br /&gt;&lt;br /&gt;&gt;apt-get install php5-mysql&lt;br /&gt;&gt;apt-get install php5&lt;br /&gt;&gt;apt-get install libapache2-mod-php5&lt;br /&gt;&gt;apt-get install php5-gd    {PHP Grafik modulu}&lt;br /&gt;&lt;br /&gt;4. MySql Kurulumu&lt;br /&gt;&lt;br /&gt;&gt;apt-get install mysql-server&lt;br /&gt;&gt;apt-get install mysql-query-browser&lt;br /&gt;&lt;br /&gt;5. Java kurulumu&lt;br /&gt;&lt;br /&gt;&lt;a href="http://java.sun.com/javase/downloads/index.jsp"&gt;java.sun.com&lt;/a&gt; üzerinden istediğiniz Java sürümüne ait kurulum paketini indirelim&lt;br /&gt;&lt;br /&gt;&gt;./jdk***.bin&lt;br /&gt;&gt;mv jdk** /usr/.&lt;br /&gt;&gt;/usr/bin/update-alternatives --install /usr/bin/java java /usr/jdk***/bin/java 0&lt;br /&gt;&gt;java -version  {bu komut ile kurulumu kontrol edelim}&lt;br /&gt;&lt;br /&gt;JAVA_HOME sistem değişkenlerinin tanımlanması gerekli. Bunun için&lt;br /&gt;&lt;br /&gt;&gt;vi /usr/profile.d/java.sh&lt;br /&gt;&lt;br /&gt;içerisine aşağıdaki tanımlamaları yapalım.&lt;br /&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;JAVA_HOME=/usr/jdk***&lt;br /&gt;PATH=$PATH:$JAVA_HOME/bin&lt;br /&gt;CLASSPATH=.&lt;br /&gt;export JAVA_HOME PATH CLASSPATH&lt;br /&gt;&lt;br /&gt;6. DB2 Express C kurulumu&lt;br /&gt;&lt;br /&gt;IBM'in sitesinden ücretsiz olan DB2 Express C'ye ait uygun sürümü &lt;a href="http://www-01.ibm.com/software/data/db2/express/download.html?S_TACT=index&amp;amp;S_CMP=expcsite"&gt;buradan&lt;/a&gt; indirelim.&lt;br /&gt;&lt;br /&gt;&gt;apt-get install libstdc++5&lt;br /&gt;&gt;apt-get install libaio-dev&lt;br /&gt;&gt;./db2setup&lt;br /&gt;&lt;br /&gt;kurulum sonundan bazı işlemleri yaparken hata oluştuğunu söyleyecektir.&lt;br /&gt;bilgisayarınızı yeniden başlatın.&lt;br /&gt;&lt;br /&gt;&gt;db2    {ile kurulumu kontrol edelim}&lt;br /&gt;&lt;br /&gt;uzaktaki bir db2 veritabanına erişmek için&lt;br /&gt;&lt;br /&gt;&gt;db2 catalog tcpip node NODE_NAME remote SERVER_HOSTNAME/SERVER_IP server SERVER_PORT&lt;br /&gt;&gt;db2 catalog db DB_NAME at node NODE_NAME&lt;br /&gt;&gt;db2 list db directory {tanımlamaları kontrol edelim}&lt;br /&gt;&gt;db2 DB_NAME user USERNAME&lt;br /&gt;&lt;br /&gt;7. Tomcat Kurulumu&lt;br /&gt;&lt;br /&gt;Uygun Tomcat sürümüne ait kurulum paketini indirelim&lt;br /&gt;&lt;br /&gt;&gt;tar zxvf apache-tomcat-***.tgz&lt;br /&gt;&lt;br /&gt;8. Eclipse Kurulumu&lt;br /&gt;&lt;br /&gt;www.eclipse.org sitesinden uygun Eclipse Versiyonu indirilir.&lt;br /&gt;&lt;br /&gt;&gt;tar zxvf eclipse-****.tgz&lt;br /&gt;&lt;br /&gt;9. SVN kurulumu&lt;br /&gt;&lt;br /&gt;&gt;apt-get install svn&lt;br /&gt;&lt;br /&gt;10. Apache-Maven kurulumu&lt;br /&gt;&lt;br /&gt;&lt;a href="http://maven.apache.org/download.html"&gt;&lt;/a&gt;Uygun Maven paketini &lt;a href="http://maven.apache.org/download.html"&gt;buradan&lt;/a&gt; indirebilirsiniz.&lt;br /&gt;&gt;tar zxvf apache-maven***.tgz&lt;br /&gt;&gt;mv apache-maven*** /usr/.&lt;br /&gt;&gt;ln -s /usr/apache-maven***/bin/mvn /usr/bin/mvn&lt;br /&gt;&lt;br /&gt;11. Tomcat'i servis olarak calistirma&lt;br /&gt;&lt;br /&gt;12. Network Manager Applet kablosuz aglari listeyemiyordu. bunun icin asagidaki komutlari calistirarak kurulumu tekrar yaptim ve kablosuz aglar listelenmeye basladi.&lt;br /&gt;&lt;br /&gt;&gt;apt-get remove network-manager&lt;br /&gt;&gt;apt-get install network-manager network-manager-gnome&lt;br /&gt;&lt;br /&gt;Sisteminizde var olan pci donanimlari listelemek icin asagidaki komutu kullanabilirsiniz.&lt;br /&gt;&lt;br /&gt;&gt;lspci --nn&lt;br /&gt;&lt;br /&gt;13. Editplus kurma&lt;br /&gt;&lt;br /&gt;apt-get install wine&lt;br /&gt;wget ftp://ftp.editplus.com/epp231_en.exe&lt;br /&gt;wine ./epp231_en.exe&lt;br /&gt;&lt;br /&gt;14. OpenVpn ve diğer vpn profillerinin yönetimi&lt;br /&gt;&lt;br /&gt; sudo apt-get install openvpn&lt;br /&gt; sudo apt-get install kvpnc&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-4828580932865944626?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/4828580932865944626/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=4828580932865944626' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/4828580932865944626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/4828580932865944626'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/03/ubuntu-ile-uygulama-gelistirme-ortam.html' title='Ubuntu ile Uygulama Geliştirme Ortamı oluşturalım'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-5819703232260895551</id><published>2010-01-27T03:12:00.000-08:00</published><updated>2010-01-27T04:37:13.382-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Apache Wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Apache Wicket ile DialogBox oluşturma</title><content type='html'>Bileşen bazı web çatısı (&lt;a style="color: rgb(204, 0, 0);" href="http://en.wikipedia.org/wiki/Component-based_software_engineering"&gt;Component Based&lt;/a&gt; &lt;a style="color: rgb(51, 51, 255);" href="http://en.wikipedia.org/wiki/Web_framework"&gt;Web Framework&lt;/a&gt;) olan &lt;a href="http://en.wikipedia.org/wiki/Apache_Wicket"&gt;Apache Wicket&lt;/a&gt; ile kendimize ait bileşenler oluşturmak çok kolay. Web uygulamalarımızda çok kullandığımız kullanıcı yönlendirici mesajları göstermek için bir Wicket Bileşeni nasıl oluştururuz gelin hep birlikte görelim.&lt;br /&gt;&lt;br /&gt;Apache Wicket ile Bileşen Tabanlı (Component Based) Web uygulaması gerçekleştirmek kolay ve zevkli bir iş haline geliyor. Bir iki klavye hamlesi ile &lt;a href="http://en.wikipedia.org/wiki/Ajax_%28programming%29"&gt;AJAX&lt;/a&gt; uygulaması yazabilirsiniz.&lt;br /&gt;&lt;br /&gt;Uygulamalarda kullanıcı bilgilendirme mesajları kimi zaman ilgili formun üzerinde, form girişlerinin yanında ve ya ayrı sayfalarda gösterilmektedir. Bu mesajların gösterimindeki görsel uyumluluk kullanıcının mesajı okumadan içeriği hakkında bilgi sahibi olmasını sağlar. Yönlendirme düğmeleri (button) kullanılarak  hangi işleme  devam etmesi seçenek olarak sunulur.&lt;br /&gt;&lt;br /&gt;Aşağıdaki gibi bir mesaj kutusu tasarladım.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_26g2bnq8gh_b" style="width: 453px; height: 241px;" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1. SUCCESS, INFO, WARNING, ERROR ve UNAUTHORIZED şeklinde 5 tip mesaj gösterebiliriz.&lt;br /&gt;2. Her mesaj tipinin kendisine ait logosu olacak.&lt;br /&gt;3. Bazı genel mesajlarda title ve footer alanı olmayacak.&lt;br /&gt;4. İstediğim kadar yönlendirme düğmesi ekleyebilmeliyim.&lt;br /&gt;&lt;br /&gt;Çizmiş olduğumuz arayüz tasarımını, tasarımcıya verip HTML ve CSS kodlamalarını gerçekleştirelim.&lt;br /&gt;&lt;br /&gt;HTML kodları içerisinde Apache Wicket bileşenlerine &lt;span style="font-weight: bold;"&gt;wicket:id&lt;/span&gt; eklemesini yapalım.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_27gvpvdbg2_b" style="width: 504px; height: 207px;" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Wicket bileşenleri:&lt;br /&gt;&lt;br /&gt;1. Mesaj Logosu&lt;br /&gt; 2. Mesaj Başlık Panel’i&lt;br /&gt; 3. Mesaj Başlığı (Title)&lt;br /&gt; 4. Mesaj Gövdesi (Body)&lt;br /&gt; 5. Mesaj Sonu (Footer)&lt;br /&gt; 6. Yönlendirme Düğmeleri (Buttons)&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;wicket:panel&amp;gt;&lt;br /&gt;&amp;lt;div class="msg_container"&amp;gt;&lt;br /&gt;&amp;lt;div class="msg_body"&amp;gt;&lt;br /&gt;&amp;lt;table border="0" cellpadding="0" cellspacing="0"&amp;gt;&lt;br /&gt;&amp;lt;tr&amp;gt;&lt;br /&gt;    &amp;lt;td width="160"&amp;gt;&amp;lt;img wicket:id="logo"/&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;    &amp;lt;td&amp;gt;&amp;lt;div wicket:id="titlePanel"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;    &amp;lt;br /&amp;gt;&amp;lt;span wicket:id="body"&amp;gt;[body]&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;    &amp;lt;br /&amp;gt;&amp;lt;span wicket:id="footer"&amp;gt;[footer]&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;          &amp;lt;div style=" margin-right: 30px;"&amp;gt;&lt;br /&gt;             &amp;lt;div wicket:id="buttons" style="float:right; margin-right:15px;" &amp;gt;&lt;br /&gt;               &amp;lt;input type="button" wicket:id="button"/&amp;gt;&lt;br /&gt;           &amp;lt;/div&amp;gt;&lt;br /&gt;        &amp;lt;/div&amp;gt;&lt;br /&gt;          &amp;lt;div style="clean: both"/&amp;gt;&lt;br /&gt;    &amp;lt;/td&amp;gt;&lt;br /&gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;&amp;lt;/table&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/wicket:panel&amp;gt;&lt;br /&gt;&lt;/pre&gt;Neden mesaj başlığını bir panel içerisine koyuyoruz? Cevabı basit, başlığı olmayan bir mesaj göstermek istediğimde gövdenin yukarısında göze batacak kadar boşluk olmasını istemiyorum. Bu yüzden burada bulunan div’i gizlemem gerek. Bunun için de başlığın bulunduğu div’e bir wicket panel’i olarak işlem yapacağım.&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;wicket:panel&amp;gt;&lt;br /&gt;&amp;lt;strong &amp;gt;&lt;br /&gt;&amp;lt;span wicket:id="title"&amp;gt;[title]&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;lt;/strong&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;&amp;lt;/wicket:panel&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;UML Sınıf Diyagramım aşağıdaki gibi olacaktır:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_30w58g6jc9_b" style="width: 575px; height: 456px;" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Gösterilecek olan başlık anahtarını, içerik anahtarını (ResourceBundle Key), düğmeleri taşıyacak Message sınıfı oluşturdum.&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class Message implements Serializable {&lt;br /&gt;private MessageType type;&lt;br /&gt;private String bodyKey;&lt;br /&gt;private String footerKey;&lt;br /&gt;private List&lt;messagebutton&gt; buttons = new ArrayList&lt;messagebutton&gt;();&lt;br /&gt;&lt;br /&gt;public Message(MessageType type, String titleKey, String bodyKey,&lt;br /&gt;          String footerKey) {&lt;br /&gt;    this.type = type;&lt;br /&gt;    this.titleKey = titleKey;&lt;br /&gt;    this.bodyKey = bodyKey;&lt;br /&gt;    this.footerKey = footerKey;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void addButton(MessageButton button){&lt;br /&gt;   this.buttons.add(button);&lt;br /&gt;}&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;/messagebutton&gt;&lt;/messagebutton&gt;&lt;/pre&gt;Gösterilecek olan mesajın tipine göre logo değişimi olacaktır. Bu yüzden resim tanımlarını mesaj tipi ile ilişkilendirdim. Bunun için Enum yapısını kullanabiliriz. Eğer renk farklılığı da olması istenirse CSS tanımlarını da burada kullanabiliriz.&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public enum MessageType {&lt;br /&gt;ERROR(ConfirmMessagePanel.ERROR_IMAGE),&lt;br /&gt;INFO(ConfirmMessagePanel.INFO_IMAGE),&lt;br /&gt;SUCCESS(ConfirmMessagePanel.SUCCESS_IMAGE),&lt;br /&gt;WARNING(ConfirmMessagePanel.WARNING_IMAGE),&lt;br /&gt;DENIED(ConfirmMessagePanel.DENIED_IMAGE);&lt;br /&gt;&lt;br /&gt;private ResourceReference image;&lt;br /&gt;&lt;br /&gt;private MessageType(ResourceReference image){&lt;br /&gt;    this.image = image;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public ResourceReference getImage(){&lt;br /&gt;    return this.image;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;MessageButton soyut sınıfından oluşturacağımız her nesnenin kendine özel davranışı olacaktır. Bu yüzden soyut clickButton yordamı tanımladık. AjaxLink Wicket yapısını kullanarak butonların HTML Button’u olarak işlem görmesini Form Submit Button’u olarak tanımlanmamasını sağlarız. Parametre olarak aldığımız AjaxRequestTarget nesnesinin addCompenent() yordamını kullanarak bize Ajax Call’u sonunda hangi bileşenlerin yeniden yorumlanacağını (rendering) ve yeni HTML kodu üretileceğini belirleriz.&lt;br /&gt;&lt;pre name="code" class="java"&gt;public abstract class MessageButton extends AjaxLink {&lt;br /&gt;public MessageButton(String labelKey) {&lt;br /&gt;    super("button", new Model(labelKey));&lt;br /&gt;    this.add(new SimpleAttributeModifier("value",&lt;br /&gt;                    new ResourceModel(labelKey).getObject()));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public abstract void clickButton(AjaxRequestTarget target);&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public void onClick(AjaxRequestTarget target) {&lt;br /&gt;    this.clickButton(target);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Gelelim mesajlarımızı ve diğer görsel bileşenleri Wicket Panel ile göstermeye. Bunun için Panel Wicket yapısından türemiş MessagePanel sınıfını oluşturmalıyız.&lt;br /&gt;&lt;pre name="code" class="java"&gt;public class MessagePanel extends Panel implements IHeaderContributor {&lt;br /&gt;&lt;br /&gt;private static final long serialVersionUID = -3432489401302616102L;&lt;br /&gt;&lt;br /&gt;private ConfirmMessageModal modal;&lt;br /&gt;&lt;br /&gt;/** reference to the confirmbox's css resource */&lt;br /&gt;private static final ResourceReference CSS = new ResourceReference(&lt;br /&gt;    MessagePanel.class, "confirmbox.css");&lt;br /&gt;&lt;br /&gt;/** reference to WARNING image */&lt;br /&gt;static final ResourceReference WARNING_IMAGE = new ResourceReference(&lt;br /&gt;    MessagePanel.class, "WARNING.gif");&lt;br /&gt;&lt;br /&gt;/** reference to INFO image */&lt;br /&gt;static final ResourceReference INFO_IMAGE = new ResourceReference(&lt;br /&gt;    MessagePanel.class, "INFO.gif");&lt;br /&gt;&lt;br /&gt;/** reference to ERROR image */&lt;br /&gt;static final ResourceReference ERROR_IMAGE = new ResourceReference(&lt;br /&gt;    MessagePanel.class, "ERROR.gif");&lt;br /&gt;&lt;br /&gt;/** reference to SUCCESS image */&lt;br /&gt;static final ResourceReference SUCCESS_IMAGE = new ResourceReference(&lt;br /&gt;    MessagePanel.class, "SUCCESS.gif");&lt;br /&gt;&lt;br /&gt;/** reference to DENIED image */&lt;br /&gt;static final ResourceReference DENIED_IMAGE = new ResourceReference(&lt;br /&gt;    MessagePanel.class, "DENIED.gif");&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;* (non-Javadoc)&lt;br /&gt;*&lt;br /&gt;* @see&lt;br /&gt;* org.apache.wicket.markup.html.IHeaderContributor#renderHead(org.apache&lt;br /&gt;* .wicket.markup.html.IHeaderResponse)&lt;br /&gt;*/&lt;br /&gt;public void renderHead(IHeaderResponse response) {&lt;br /&gt;response.renderCSSReference(CSS);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public MessagePanel(String id, Message message) {&lt;br /&gt;this(id, message, false);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public MessagePanel(String id, Message message, boolean hideTitle) {&lt;br /&gt;super(id);&lt;br /&gt;&lt;br /&gt;TitlePanel titlePanel = new TitlePanel("titlePanel", new ResourceModel(&lt;br /&gt;        message.getTitleKey(), message.getBodyKey()));&lt;br /&gt;&lt;br /&gt;add(new Image("logo", message.getMessageType().getImage()));&lt;br /&gt;add(titlePanel);&lt;br /&gt;&lt;br /&gt;add(new Label("body", new ResourceModel(message.getBodyKey(), message&lt;br /&gt;        .getBodyKey())));&lt;br /&gt;&lt;br /&gt;add(new Label("footer", new ResourceModel(message.getFooterKey(), "")));&lt;br /&gt;add(new ListView&lt;messagebutton&gt;("buttons", message.getButtonList()) {&lt;br /&gt;&lt;br /&gt;    private static final long serialVersionUID = 3339539327149648078L;&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    protected void populateItem(ListItem&lt;messagebutton&gt; item) {&lt;br /&gt;        final MessageButton button = item.getModelObject();&lt;br /&gt;        item.add(button);&lt;br /&gt;    }&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;if (hideTitle) {&lt;br /&gt;    titlePanel.setVisible(false);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void setModal(ConfirmMessageModal modal) {&lt;br /&gt;this.modal = modal;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;ConfirmMessageModal getModal() {&lt;br /&gt;return this.modal;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private class TitlePanel extends Panel {&lt;br /&gt;private static final long serialVersionUID = -1766112576379965369L;&lt;br /&gt;&lt;br /&gt;public TitlePanel(String id, IModel&lt;string&gt; model) {&lt;br /&gt;    super(id, model);&lt;br /&gt;    add(new Label("title", model));&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/string&gt;&lt;/messagebutton&gt;&lt;/messagebutton&gt;&lt;/pre&gt;Yukarıda gördüğümüz gibi MessagePanel sınıfı IHeaderContributor arayüzünü gerçekleştirmiş. Eğer bir Wicket Bileşen’inin Header’da değişiklik yapmasını istiyorsak bu arayüzün renderHead() yordamını gerçekleştirmesini sağlamalıyız. CSS ve resim dosyalarının MessagePanel ile paketlemek istediğimiz için aynı dizinde bulunmalıdırlar. Wicket tarafından kullanılabilir olmaları için herbirine ait ResourceReference nesnesi oluşturuyoruz.&lt;br /&gt;&lt;br /&gt;Mesaj kutusunun inşaası yapılandırıcı içerisinde gerçekleşmekte. Yapılandırıcı dışında onBeforeRender() yordamı içerisinde de bunu gerçekleştirebiliriz.&lt;br /&gt;&lt;br /&gt;Yapılandırıcı içerisinde liste içerisindeki MessageButton’ları göstermek için ListView Wicket yapısını kullanıyoruz. Bu yapı da bir wicket html tanımına ihtiyaç duymaktadır.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;div &lt;span style="font-weight: bold;"&gt;wicket:id="buttons" &lt;/span&gt;style="float:right; margin-right:15px;" &amp;gt;&lt;br /&gt;&amp;lt;input type="button" wicket:id="button"/&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;Önceki paragraflarda title’in isteğimize göre görünmesini/görünmemesini bunu ayrı bir Wicket Panel gibi düşünerek sağlayabiliriz demiştik. Yapılandırı içerisindeki son satırlarda göndermiş olduğumuz hideTitle parametresine göre panelin setVisible(false) yordamını çağırıyoruz. Başlığı içerecek kısmı panel olarak tanımladığımız için buna ait Wicket Panel sınıfı ve html dosyası oluşturmamız gerekmektedir. Encapsulation prensiplerine uyarak bu panel sınıf tanımını private erişim belirtecine sahip Inner Class olarak yapalım.&lt;br /&gt;&lt;pre name="code" class="java"&gt;public class MessagePanel extends Panel implements IHeaderContributor {&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;private class TitlePanel extends Panel {&lt;br /&gt;...&lt;br /&gt;public TitlePanel(String id, IModel&lt;string&gt; model) {&lt;br /&gt;    super(id, model);&lt;br /&gt;    add(new Label("title", model));&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/string&gt;&lt;/pre&gt;Wicket Html tanımı ise ConfirmMessagePanel$TitlePanel.html dosyası içerisinde bulunmalı. Dikkat edildiği gibi derleme sonrasında oluşacak inner class dosya ismi ile aynı.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;wicket:panel&amp;gt;&lt;br /&gt;&amp;lt;strong &amp;gt;&amp;lt;span   wicket:id="title"&amp;gt;[title]&amp;lt;/span&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;&amp;lt;br /&amp;gt;&lt;br /&gt;&amp;lt;/wicket:panel&amp;gt;&lt;br /&gt;&lt;/pre&gt;Oluşak olan uygulama dizin yapısı aşağıdaki gibidir:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_45fjpx9vfx_b" style="width: 250px; height: 291px;" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Uygulama içerisinde MessagePanel’imizi nasıl kullanacağız? İşte burada bir örnek mevcut:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;...&lt;br /&gt;Message message = new Message(MessageType.INFO,&lt;br /&gt;        "message.panel.title",&lt;br /&gt;        "message.panel.body",&lt;br /&gt;        "message.panel.footer");&lt;br /&gt;message.addButton(new MessageButton("message.button.no"){&lt;br /&gt;...&lt;br /&gt;@Override&lt;br /&gt;public void clickButton(AjaxRequestTarget target) {&lt;br /&gt;// DO NOTHING&lt;br /&gt;}&lt;br /&gt;});&lt;br /&gt;message.addButton(new MessageButton("message.button.yes"){&lt;br /&gt;...&lt;br /&gt;@Override&lt;br /&gt;public void clickButton(AjaxRequestTarget target) {&lt;br /&gt;// DO NOTHING&lt;br /&gt;}&lt;br /&gt;});&lt;br /&gt;MessagePanel messagePanel = new MessagePanel("content", message);&lt;br /&gt;add(messagePanel);&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;Sonuç :&lt;br /&gt;&lt;br /&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_44dntq66ct_b" style="width: 575px; height: 198px;" /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Mesajlarımızın ModalBox içerisinde görünmesini istiyorsak&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Apache Wicket ile modal pencereleri yapmak çok kolay. &lt;a href="http://en.wikipedia.org/wiki/Modal_window"&gt;ModalWindow&lt;/a&gt; Wicket yapısından yeni yapılar türeterek bunu gerçekleştirebiliriz.&lt;br /&gt;&lt;br /&gt;MessagePanel nesnesini Modal özelliği katmak için sarmalayıcı bir sınıf oluşturalım. MessageModal, ModalWindow’dan türeyen bir yapı.&lt;br /&gt;&lt;pre name="code" class="java"&gt;public class MessageModal extends ModalWindow {&lt;br /&gt;&lt;br /&gt;public MessageModal(String id, Message message) {&lt;br /&gt;super(id);&lt;br /&gt;this.setMinimalHeight(176);&lt;br /&gt;this.setInitialHeight(176);&lt;br /&gt;MessagePanel panel = new MessagePanel(this.getContentId(), message, true);&lt;br /&gt;panel.setModal(this);&lt;br /&gt;this.setTitle(new ResourceModel(message.getTitleKey()));&lt;br /&gt;setContent(panel);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public void showMessage(AjaxRequestTarget target) {&lt;br /&gt;this.show(target);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;MessageModal ile gösterilen mesajlarda başlıklar pencerenin başlığı olarak görünmesini istedim. Bunun için MessagePanel’in yapılandırıcısına hideTitle parametresi için TRUE değeri gönderdim, ModalWindow’dan miras aldığım setTitle() ile ModalWindow’a başlık ataması yaptım.&lt;br /&gt;&lt;br /&gt;ModalWindow’u göstermek için show() yordamını kullanıyoruz. Bunun için Ajax desteği olan bir bileşenin oluşturduğu istek ile AjaxRequestTarget nesnesi gelmesi gerekmektedir.&lt;br /&gt;&lt;br /&gt;MessageModal’ın bir de HTML dosyası olmalı :&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;wicket:panel&amp;gt;&lt;br /&gt;&amp;lt;div wicket:id="content"/&amp;gt;&lt;br /&gt;&amp;lt;/wicket:panel&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Modal kullanımları için ilgili modal kodlarını içerecek bir Wicket Bileşeni tanımlamamız gerekmektedir.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;div wicket:id="modal"&amp;gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;br /&gt;MessagePanel oluşturur gibi MessageModal oluşturabiliriz:&lt;br /&gt;&lt;pre name="code" class="java"&gt;Message message = new Message(MessageType.SUCCESS,&lt;br /&gt;"message.modal.title",&lt;br /&gt;"message.modal.body",&lt;br /&gt;"message.modal.footer");&lt;br /&gt;message.addButton(new MessageButton("message.button.no"){&lt;br /&gt;@Override&lt;br /&gt;public void clickButton(AjaxRequestTarget target) {&lt;br /&gt;// DO NOTHING&lt;br /&gt;}&lt;br /&gt;});&lt;br /&gt;message.addButton(new MessageButton("message.button.yes"){&lt;br /&gt;@Override&lt;br /&gt;public void clickButton(AjaxRequestTarget target) {&lt;br /&gt;// DO NOTHING&lt;br /&gt;}&lt;br /&gt;});&lt;br /&gt;MessageModal messageModal = new MessageModal("modal", message);&lt;br /&gt;&lt;/pre&gt;Göstermek için ise bir Ajax olayına ihtiyacımız var. Bunun için bir önceki bölümde oluşturduğumuz MessagePanel nesnesine “Show” isimli yeni bir buton ekliyorum.&lt;br /&gt;&lt;pre name="code" class="java"&gt;message.addButton(new MessageButton("message.button.show"){&lt;br /&gt;@Override&lt;br /&gt;public void clickButton(AjaxRequestTarget target) {&lt;br /&gt;modal.showMessage(target);&lt;br /&gt;}&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Uygulamayı çalıştırıp sonucunu görelim:&lt;br /&gt;&lt;br /&gt;&lt;img src="https://docs.google.com/File?id=dcwqjq5f_46gbbs4nfc_b" style="width: 575px; height: 303.602px;" /&gt;&lt;br /&gt;&lt;br /&gt;Proje kodlarına &lt;a href="http://www.jtpd.org/files/download/MjAxMDAxMjYxNzIyMzYtcGhncHNrZW9mc3F1bHZ3Y3Yvd2lja2V0LW1lc3NhZ2Vib3gucmFy"&gt;buradan&lt;/a&gt; ulaşabilirsiniz.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-5819703232260895551?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/5819703232260895551/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=5819703232260895551' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/5819703232260895551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/5819703232260895551'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/01/bilesen-baz-web-cats-component-based.html' title='Apache Wicket ile DialogBox oluşturma'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-3629523725997802230</id><published>2010-01-22T03:59:00.000-08:00</published><updated>2011-07-27T04:54:02.601-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scalability'/><title type='text'>Tomcat Ölçeklendirilmesi</title><content type='html'>Sunucular üzerindeki aşırı yüklenmeden kaynaklanan sorunları çözmenin bir yöntemi bu yüklenmeleri bir kaç sunucuya paylaştırmak olacaktır. Aynı işi  yapan sunucuların oluşturduğu kümeden (cluster) beklenilen duruma göre küçülebilir/genişleyebilir -ölçeklenebilir- olması (scalability), kümedeki bir sunucunun durması durumunda üzerindeki isteklere başka bir sunucunun cevap vermesidir (availability). Küme yapısını iki şekilde kurabiliriz : Dikey ve Yatay. Dikey küme yapısında tek makina  üzerinde birden fazla küme üyesi bulunurken, yatay yapıda üyelerin herbiri ayrı makinalarda bulunur.&lt;br /&gt;&lt;br /&gt;Sunucuların kümelenme işlemiyle neleri gerçekleştirebiliriz?&lt;br /&gt;&lt;br /&gt;1. İş yükünü dağıtma (Load Balanbcing)Geliştirdiğimiz web tabanlı uygulamalarda bir çoğumuz Apache, Tomcat, J2EE uygulama sunucularını kullanmışızdır. Yazdığımız uygulamaları kullanan sayısı arttıkça, artan isteğe cevap vermeye çalışan sunucuların da istiktrarlı çalışması beklenemez. Bu gibi durumda yazdığımız uygulamadaki dar boğazların neler olduğunu tespit etmeye çalışırız. Bu dar boğazların tespiti ve düzeltilmesi için uygulamalarda ciddi yapısal değişiklikleri yapmamız yazılım maaliyetlerinin artmasına neden olmaktadır.&lt;br /&gt;2. Hata yönetimi  (Fault Tolerance)&lt;br /&gt;3. Kullanıcı oturumlarının paylaşılması (Session Persistence)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Tomcat 5 ve Clustering&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Tomcat 5 sunucularında küme yapısını aktif hale getirmek için server.xml dosyasındaki &lt;cluster&gt;&lt;/cluster&gt; tanımlamasını aktif hale getirmemiz gerekmektedir.&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&lt;cluster classname="org.apache.catalina.cluster.tcp.SimpleTcpCluster" managerclassname="org.apache.catalina.cluster.session.DeltaManager" expiresessionsonshutdown="false" usedirtyflag="true"&gt;&lt;br /&gt;&lt;/cluster&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Tomcat 5 küme yapısındaki sunucular çalıştıklarını bildirmek (heartbeating) ve kullanıcı oturumlarını (session) aktarmak için birbirleri ile konuşmaya ihtiyaç duymaktadırlar.&lt;br /&gt;IP multicast yöntemi ile her bir küme üyesi diğer üyelerin durumu hakkında bilgi almaktadır. Durum sorgu mesajı kümeye gönderildiğinde cevap olarak cevap verenin IP adresi ve port numarası alınmaktadır. Tüm üyeler için MultiCast tanımlaması aynı olmalıdır.  Örnek :&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&lt;cluster&gt;&lt;br /&gt;...&lt;br /&gt;&lt;membership classname="org.apache.catalina.cluster.mcast.McastService" mcastaddr="228.0.0.4" mcastport="45564" mcastfrequency="500" mcastdroptime="3000"&gt;&lt;br /&gt;&lt;/membership&gt;&lt;br /&gt;&lt;/cluster&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;IP / Socket iletişimi oturum bilgilerinin diğer üyelere gönderilmesi ve üyelerden alınması için kullanılmaktadır.&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&lt;cluster&gt;&lt;br /&gt;&lt;receiver classname="org.apache.catalina.cluster.tcp.ReplicationListener" tcplistenaddress="127.0.0.1" tcplistenport="4000" tcpselectortimeout="100" tcpthreadcount="6"&gt;&lt;br /&gt;&lt;sender classname="org.apache.catalina.cluster.tcp.ReplicationTransmitter" replicationmode="pooled"&gt;&lt;br /&gt;&lt;/sender&gt;&lt;br /&gt;&lt;/receiver&gt;&lt;/cluster&gt;&lt;/pre&gt;&lt;br /&gt;tcpListenerAddress ve tcpListenPort  değerleri herbir küme üyesi için farklı olmalıdır. IP multicast yöntemi ile gelen sorguya cevap olarak bu bilgiler gönderilmektedir.&lt;br /&gt;Receiver tanımlaması, tanımlamanın yapıldığı küme üyesinin gelen paylaşım paketlerinin kaç thread tarafından ve hangi port üzerinden alınacağını belirler.&lt;br /&gt;Sender tanımlaması, oturum bilgisinin gönderilme yöntemini belirler : synchronous, pooled (default), asynchronous&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;asynchronous :&lt;/span&gt; bu modda, oturum bilgisini diğer üyelere gönderen thread, istek geldiğinde paylaşımı işlemini kuyruğa sokup hemen gelen isteğe cevap verme kaygısı içerisindedir. Bu modda kullanıcıya kısa sürede cevap verilmektedir. Oturum bilgisinin paylaşımının başarısız olması çok önemli değildir.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;synchronous :&lt;/span&gt; bu modda, oturum paylaşımı tam anlamıyla gerçekleşmeden kullanıcı isteğine cevap dönülmemektedir. Paylaşım işlemi tek thread üzerinden gerçekleştiğinden, üye sayısı çok olan kümede istemciye cevap verme süresi artacaktır.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;pooled :&lt;/span&gt; bu modda, gönderilecek olan paylaşım bilgisi parçalara ayrılarak her biri farklı thread ve soket üzerinden gönderilmektedir.  Gönderme işlemi yapıldıktan sonra istemciye cevap verilmektedir.&lt;br /&gt;&lt;br /&gt;Oturum bilgisi paylaşımı 3 durumda gerçekleşir:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;userDirtyFlag parametresi true olarak ayarlanmışsa veya setAttribute() / removeAttribute() yordamları çağrılmışsa&lt;/li&gt;&lt;li&gt;Oturum yaratıldığında&lt;/li&gt;&lt;li&gt;Valve tanımı içerisindeki uzantı tanımları. Bu uzantılara ait istekler geldiğinde oturum bilgisi paylaşımı gerçekleşmez. userDirtyFlag parametresi true yapıldığında Valve içerisinde tanımlananların dışında istek geldiğinde otomatik olarak paylaşım gerçekleştirilir.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;...&lt;br /&gt;&lt;valve classname="org.apache.catalina.cluster.tcp.ReplicationValve" filter=".*\.gif;.*\.js;.*\.jpg;.*\.htm;.*\.html;.*\.txt;"&gt;&lt;br /&gt;&lt;/valve&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Oturum bilgilerinin toplanması için üç yöntem mevcuttur:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Bellekten Belleğe (Memory to Memory) : &lt;/span&gt;bir küme üyesi üzerindeki oturum bilgisi değiştiğinde hemen diğer üyelere gönderilir.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Veritabanına Yazmak :&lt;/span&gt; Oturum bilgilerini veritabanına yazmak ve buradan okumak.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Dosyaya Yazmak  / Dosyadan Okumak: &lt;/span&gt;Oturum bilgilerini ortak bir dizin içerisinde dosyaya yazmak ve dosyadan okumak. Bu yöntemde bizi kısıtlayan, disk büyüklüğü olacaktır.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Aynı makina üzerinde 4 Tomcat sunucusundan oluşan dikey bir küme (vertical cluster) oluşturalım. Port çakışmalarını önlemek için her Tomcat'in server.xml dosyasında gerekli portları aşağıdaki gibi değiştirelim.&lt;table style="width: 641px; height: 444px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Konfigurasyon Parametreleri&lt;/td&gt;&lt;td&gt;üye 1&lt;/td&gt;&lt;td&gt;üye 2&lt;/td&gt;&lt;td&gt;üye 3&lt;/td&gt;&lt;td&gt;üye 4&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Instance Type&lt;/td&gt;&lt;td&gt;Load Balancer&lt;/td&gt;&lt;td&gt;Cluster Node 1&lt;/td&gt;&lt;td&gt;Cluster Node 2&lt;/td&gt;&lt;td&gt;Cluster Node 3&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Code name&lt;/td&gt;&lt;td&gt;TC01&lt;/td&gt;&lt;td&gt;TC02&lt;/td&gt;&lt;td&gt;TC03&lt;/td&gt;&lt;td&gt;TC04&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Home Directory&lt;/td&gt;&lt;td&gt;/tomcat51&lt;/td&gt;&lt;td&gt;/tomcat52&lt;/td&gt;&lt;td&gt;/tomcat53&lt;/td&gt;&lt;td&gt;/tomcat54&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Server Port&lt;/td&gt;&lt;td&gt;8005&lt;/td&gt;&lt;td&gt;9005&lt;/td&gt;&lt;td&gt;10005&lt;/td&gt;&lt;td&gt;11005&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Connector&lt;/td&gt;&lt;td&gt;8080&lt;/td&gt;&lt;td&gt;9080&lt;/td&gt;&lt;td&gt;10080&lt;/td&gt;&lt;td&gt;11080&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Coyote/JK2 AJP Connector&lt;/td&gt;&lt;td&gt;8009&lt;/td&gt;&lt;td&gt;9009&lt;/td&gt;&lt;td&gt;10009&lt;/td&gt;&lt;td&gt;11009&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Cluster mcastAddr&lt;/td&gt;&lt;td&gt;228.0.0.4&lt;/td&gt;&lt;td&gt;228.0.0.4&lt;/td&gt;&lt;td&gt;228.0.0.4&lt;/td&gt;&lt;td&gt;228.0.0.4&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Cluster mcastPort&lt;/td&gt;&lt;td&gt;45564&lt;/td&gt;&lt;td&gt;45564&lt;/td&gt;&lt;td&gt;45564&lt;/td&gt;&lt;td&gt;45564&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;tcpListenAddress&lt;/td&gt;&lt;td&gt;127.0.0.1&lt;/td&gt;&lt;td&gt;127.0.0.1&lt;/td&gt;&lt;td&gt;127.0.0.1&lt;/td&gt;&lt;td&gt;127.0.0.1&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;Cluster tcpListenPort&lt;/td&gt;&lt;td&gt;4000&lt;/td&gt;&lt;td&gt;4001&lt;/td&gt;&lt;td&gt;4002&lt;/td&gt;&lt;td&gt;4003&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Tüm küme üyelerini aktif hale getirelim. TC01'den alınan log çıktısında, TC01 'in küme içerisinde hangi üyelerin olduğunu ve yaşadığını tespit etmek için gönderdiği ve aldığı mesajları görmekteyiz. Bu işlemleri tüm küme üyeleri kendileri için gerçekleştireceklerdir.&lt;br /&gt;&lt;div style="background-color: rgb(204, 204, 204);"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;2008-02-07 02:25:57,320 (McastServiceImpl.java:280) org.apache.catalina.cluster.mcast.McastService - Mcast send ping from member org.apache.catalina.cluster.mcast.McastMember[tcp://127.0.0.1:4000,catalina,127.0.0.1,4000, alive=2426682]&lt;br /&gt;2008-02-07 02:25:57,320 (McastServiceImpl.java:244) org.apache.catalina.cluster.mcast.McastService - Mcast receive ping from member org.apache.catalina.cluster.mcast.McastMember[tcp://127.0.0.1:4000,catalina,127.0.0.1,4000, alive=2426948]&lt;br /&gt;2008-02-07 02:25:57,450 (McastServiceImpl.java:244) org.apache.catalina.cluster.mcast.McastService - Mcast receive ping from member org.apache.catalina.cluster.mcast.McastMember[tcp://127.0.0.1:4003,catalina,127.0.0.1,4003, alive=4118285]&lt;br /&gt;2008-02-07 02:25:57,452 (McastServiceImpl.java:244) org.apache.catalina.cluster.mcast.McastService - Mcast receive ping from member org.apache.catalina.cluster.mcast.McastMember[tcp://127.0.0.1:4002,catalina,127.0.0.1,4002, alive=4122490]&lt;br /&gt;2008-02-07 02:25:57,820 (McastServiceImpl.java:244) org.apache.catalina.cluster.mcast.McastService - Mcast receive ping from member org.apache.catalina.cluster.mcast.McastMember[tcp://127.0.0.1:4001,catalina,127.0.0.1,4001, alive=2783164]&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;TC01 de clusterapp uygulamasını açalım ve birkaç giriş yapalım. Aynı pencerede URL üzerinden HTTP portunu 10080 yaparak isteği TC03 e yönlendirelim. Aynı pencereden istek yaptığımızdan sunucuya aynı oturum kimliği gidecektir. Bu kimlik JSESSIONID isminde çerez olarak tutulmaktadır.&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_9vaXx_lumNA/S1mdGvKHZhI/AAAAAAAAAIs/5r2z5oIPNzg/s1600-h/ekran_1.JPG"&gt;&lt;img style="cursor: pointer; width: 268px; height: 320px;" src="http://1.bp.blogspot.com/_9vaXx_lumNA/S1mdGvKHZhI/AAAAAAAAAIs/5r2z5oIPNzg/s320/ekran_1.JPG" alt="" id="BLOGGER_PHOTO_ID_5429543564835513874" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_9vaXx_lumNA/S1mdM020qeI/AAAAAAAAAI0/D5LkN4vnoyk/s1600-h/ekran_2.JPG"&gt;&lt;img style="cursor: pointer; width: 270px; height: 320px;" src="http://3.bp.blogspot.com/_9vaXx_lumNA/S1mdM020qeI/AAAAAAAAAI0/D5LkN4vnoyk/s320/ekran_2.JPG" alt="" id="BLOGGER_PHOTO_ID_5429543669444422114" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;TC01 da 8080 portu üzerinden yapılan işlemler&lt;/td&gt;&lt;td&gt;Aynı browser penceresindeki URL'in portunu 10080 yapınca TC03 den gelen cevap&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Isteği TC03 e yönlendirdiğimizde, TC01 üzerinden eklediğimiz ad ve soyad özelliklerini içeren aynı oturum  bilgisi gelmektedir. Peki arka tarafta neler oldu?&lt;br /&gt;TC01 deki log dosyasına bir bakalım. 4002 portlu TC03 üzerinden  7C792502AA128b28866E7E37AB6A31E8 numaralı oturum bilgisine erişilmek istendiğini görmekteyiz. İlk adımda 15 ms'lik bir sürede oturum bilgisi diğer üyelere gönderilmiş, ikinci adımda TC03'ün oturum bilgisine erişmek istediği mesajı alınmış ve üçüncü adımda bu oturum bilgisine erişilmiştir..&lt;br /&gt;&lt;div style="background-color: rgb(204, 204, 204);"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;2008-02-07 02:25:57,054 (SimpleTcpCluster.java:1163) org.apache.catalina.cluster.tcp.SimpleTcpCluster - Assuming clocks are synched: Replication for 7C792502AA128b28866E7E37AB6A31E8-1202343957039 took=15 ms.&lt;br /&gt;&lt;br /&gt;2008-02-07 02:25:57,054 (DeltaManager.java:1521) org.apache.catalina.cluster.session.DeltaManager - Manager [/clusterapp]: Received SessionMessage of type=(SESSION-ACCESSED) from [org.apache.catalina.cluster.mcast.McastMember[tcp://127.0.0.1:4002,catalina,127.0.0.1,4002, alive=4122078]]&lt;br /&gt;2008-02-07 02:25:57,055 (DeltaManager.java:1618) org.apache.catalina.cluster.session.DeltaManager - Manager [/clusterapp]: received session [7C792502AA128b28866E7E37AB6A31E8] accessed.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Uygulama Yükleme (Deploying)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Tomcat sunucusuna uygulama yükleme işlemini ya Manager üzerinden yada elle war dosyasını webapps altına taşıyarak v.b. gerçekleştirebiliriz. Bunu küme yapısı içerisinde birden fazla küme üyesine (sayısı 5-6 ve ya daha fazla da olabilir) yaptığımızı düşünelim.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;yeni war dosyasını tüm üyelere kopyala&lt;/li&gt;&lt;li&gt;her bir üyenin çalıştığı makinaya teker teker login ol&lt;/li&gt;&lt;li&gt;mevcut war dosyasını yedekle&lt;/li&gt;&lt;li&gt;yeni war dosyasını, webapps içerisine taşı&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Tamamiyle zaman kaybı, yorgunluk ve sonucunda en ufak bir hata...&lt;br /&gt;Küme yapısında uygulama yükleme işlemini tek bir yerden gerçekleştirebiliriz. Bunun için catalina-cluster.jar içerisindeki org.apache.catalina.cluster.deploy.FarmWarDeployer sınıfını yükleme işleminden sorumlu hale getiriyoruz. Server.xml dosyasında&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&lt;cluster&gt;&lt;br /&gt;&lt;deployer classname="org.apache.catalina.cluster.deploy.FarmWarDeployer" watchdir="/home/tdiler/clustering/deploy/watch" deploydir="/home/tdiler/clustering/tomcat51/webapps" watchenabled="true"&gt;&lt;br /&gt;&lt;/deployer&gt;&lt;br /&gt;&lt;/cluster&gt;&lt;/pre&gt;&lt;br /&gt;tanımlamasını yapmamız gerekmektedir. Burada &lt;span style="font-weight: bold;"&gt;watchDir&lt;/span&gt; olarak tanımladığımız dizin sürekli &lt;span style="font-weight: bold;"&gt;org.apache.catalina.cluster.deploy.WarWatcher&lt;/span&gt; tarafından dinlenmektedir. &lt;span style="font-weight: bold;"&gt;watchEnabled&lt;/span&gt; özelliği &lt;span style="font-weight: bold;"&gt;false&lt;/span&gt; yapıldığında dinleme gerçekleşmeyecektir. &lt;span style="font-weight: bold;"&gt;watchDir&lt;/span&gt; dizininde war dosyası ekleme, silme veya güncelleme işlemi yapıldığında aynı işlem &lt;span style="font-weight: bold;"&gt;deployDir&lt;/span&gt; dizininde otomatik olarak gerçekleştirilecektir. WatchEnabled özelliği true yapılan küme üyesi &lt;span style="font-weight: bold;"&gt;deployDir&lt;/span&gt; dizinindeki bir değişikliği tüm üyelere bildirmektedir. Eğer war dosyası eklenmiş veya güncellenmiş ise bu war dosyası diğer üyelere TCP üzerinden gönderilmektedir.&lt;br /&gt;TC01 üyesinde watchEnabled özelliğini true, diğerlerinde ise false (diğer üyeleri false yapma zorunluluğumuz yoktur.) yapalım. Böylece TC01 güncel WAR dosyalarının takibinden sorumlu olsun. Burada kritik bir nokta TC01 kapandığında diğer üyeler güncellemelerden haberdar olamayacaklardır. WatchDir dizinine clustering_test-0.0.2.war dosyasını koyduğumda TC01 deki log dosyasında :&lt;br /&gt;&lt;div style="background-color: rgb(204, 204, 204);"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Feb 26, 2008 12:30:48 AM org.apache.catalina.cluster.deploy.WarWatcher check&lt;br /&gt;&lt;br /&gt;INFO: check cluster wars at /home/tdiler/Documents/Tomcat_Clustring_Calisma/deploy/watch&lt;br /&gt;&lt;br /&gt;Feb 26, 2008 12:30:48 AM org.apache.catalina.cluster.deploy.FarmWarDeployer fileModified&lt;br /&gt;&lt;br /&gt;INFO: Installing webapp[/clustering_test-0.0.2] from /home/tdiler/Documents/Tomcat_Clustring_Calisma/tomcat51/webapps/clustering_test-0.0.2.war&lt;br /&gt;Feb 26, 2008 12:30:48 AM org.apache.catalina.cluster.deploy.FarmWarDeployer remove&lt;br /&gt;INFO: Cluster wide remove of web app /clustering_test-0.0.2&lt;br /&gt;Feb 26, 2008 12:30:48 AM org.apache.catalina.startup.HostConfig deployWAR&lt;br /&gt;INFO: Deploying web application archive clustering_test-0.0.2.war&lt;br /&gt;&lt;br /&gt;Feb 26, 2008 12:30:48 AM org.apache.catalina.cluster.session.DeltaManager start&lt;br /&gt;&lt;br /&gt;INFO: Starting clustering manager...:/clustering_test-0.0.2&lt;br /&gt;&lt;br /&gt;Feb 26, 2008 12:30:48 AM org.apache.catalina.cluster.session.DeltaManager start&lt;br /&gt;&lt;br /&gt;INFO: Register manager /clustering_test-0.0.2 to cluster element Host with name localhost&lt;br /&gt;&lt;br /&gt;Feb 26, 2008 12:30:48 AM org.apache.catalina.cluster.session.DeltaManager start&lt;br /&gt;&lt;br /&gt;INFO: Starting clustering manager at /clustering_test-0.0.2&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Burada &lt;span style="font-weight: bold;"&gt;org.apache.catalina.cluster.deploy.WarWatcher&lt;/span&gt; ile watchDir sürekli kontrol edilmektedir. War dosyası eklendiğinde ya da güncellendiğinde öncelikle tüm kümedeki üyelere eskisinin silinmesi için mesaj yollanmış ve sonrasında war dosyası diğer küme üyelerine gönderilmiştir. İşlem gerçekleştikten sonra bu uygulama için küme işlemleri başlatılmıştır.&lt;br /&gt;&lt;br /&gt;Dinleyici moddaki TC02 deki log dosyasına baktığımızda :&lt;br /&gt;&lt;div style="background-color: rgb(204, 204, 204);"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Feb 26, 2008 12:30:48 AM org.apache.catalina.cluster.session.DeltaManager stop&lt;br /&gt;&lt;br /&gt;INFO: Manager [/clustering_test-0.0.2] expiring sessions upon shutdown&lt;br /&gt;&lt;br /&gt;Feb 26, 2008 12:30:48 AM org.apache.catalina.startup.HostConfig checkResources&lt;br /&gt;&lt;br /&gt;INFO: Undeploying context [/clustering_test-0.0.2]&lt;br /&gt;&lt;br /&gt;Feb 26, 2008 12:30:48 AM org.apache.catalina.startup.HostConfig deployWAR&lt;br /&gt;&lt;br /&gt;INFO: Deploying web application archive clustering_test-0.0.2.war&lt;br /&gt;&lt;br /&gt;Feb 26, 2008 12:30:48 AM org.apache.catalina.cluster.session.DeltaManager start&lt;br /&gt;&lt;br /&gt;INFO: Starting clustering manager...:/clustering_test-0.0.2&lt;br /&gt;&lt;br /&gt;Feb 26, 2008 12:30:48 AM org.apache.catalina.cluster.session.DeltaManager start&lt;br /&gt;&lt;br /&gt;INFO: Register manager /clustering_test-0.0.2 to cluster element Host with name localhost&lt;br /&gt;&lt;br /&gt;Feb 26, 2008 12:30:48 AM org.apache.catalina.cluster.session.DeltaManager start&lt;br /&gt;&lt;br /&gt;INFO: Starting clustering manager at /clustering_test-0.0.2&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Var olan war dosyası silinmeden önce bu uygulama için başlatılan küme işlemleri durdurulmuş, yeni war dosyası alınmış ve işlemler yeniden başlatılmıştır.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Kaynaklar&lt;/span&gt;&lt;br /&gt;1. &lt;a href="http://www.onjava.com/pub/a/onjava/2004/03/31/clustering.html"&gt;Clustering and Load Balancing in Tomcat 5, Part 1; Srini Penchikala&lt;/a&gt;&lt;br /&gt;2. &lt;a href="http://www.onjava.com/pub/a/onjava/2004/11/24/replication1.html"&gt;Session Replication in Tomcat 5 Clusters, Part 1; Srini Penchikala&lt;/a&gt;&lt;br /&gt;3. &lt;a href="http://tomcat.apache.org/tomcat-5.5-doc/cluster-howto.html"&gt;Apache Tomcat 5.5 Clustering/Session Replication HOW-TO&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-3629523725997802230?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/3629523725997802230/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=3629523725997802230' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/3629523725997802230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/3629523725997802230'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/01/tomcat-olceklendirilmesi.html' title='Tomcat Ölçeklendirilmesi'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_9vaXx_lumNA/S1mdGvKHZhI/AAAAAAAAAIs/5r2z5oIPNzg/s72-c/ekran_1.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-7039525414174541322</id><published>2010-01-16T12:15:00.000-08:00</published><updated>2011-07-27T04:54:43.809-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='versiyonlama sistemi'/><title type='text'>Çevik Takımlar ve Versiyonlama Sistemi Kullanımı</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/Revision_control"&gt;Versiyonlama sistemleri&lt;/a&gt; (versioning systems) içerisinde &lt;a href="http://subversion.tigris.org/"&gt;SVN&lt;/a&gt;, özellikleri ile &lt;a href="http://en.wikipedia.org/wiki/Open_source"&gt;açık kaynak kodlu&lt;/a&gt; projelerde (Open Source Project) ve &lt;a href="http://en.wikipedia.org/wiki/Agile_software_development"&gt;çevik takımlarda&lt;/a&gt; en çok kullanılanı olmuştur.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://mercurial.selenic.com/"&gt;Mercurial&lt;/a&gt; Versiyonlama Sistemi ile desteklenmiş bir ortamda ise ana depodan (repository)  - bu depo SVN, Mercurial olabilir - oluşturulan Mercurial depoları ile her kullanıcı offline olarak kodlarını kendi Mercurial deposuna commit yapabilir. Online duruma geçtiğinde kendi deposunu ana depo ile senkronize hale getirebilir.&lt;br /&gt;&lt;br /&gt;Açık kaynak kodlu projelerde benimsenen belli bir depo (repository) yapısı mevcuttur:&lt;br /&gt;&lt;br /&gt;Depo (Repository)&lt;br /&gt;|&lt;br /&gt;|&lt;br /&gt;|- Proje_1&lt;br /&gt;|&lt;br /&gt;|-trunk&lt;br /&gt;|-branhces&lt;br /&gt;|-releases/tags&lt;br /&gt;|-site&lt;br /&gt;|-sandbox&lt;br /&gt;|&lt;br /&gt;|-developer_1&lt;br /&gt;|-developer_2&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;trunk :&lt;/span&gt; Geliştirme patikalarının (branch) oluşturulduğu, her zaman deploy edilebilir kodların bulunduğu ana proje hattıdır.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;branches :&lt;/span&gt; Geliştirmelerin yapılacağı, trunk'dan oluşturulan patikalardır. Trunk'dan oluşturulabilecekleri gibi başka bir patikadan da oluşturulabilirler.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;releases / tags :&lt;/span&gt; Trunk üzerinde gerçekleştirilen &lt;a href="http://en.wikipedia.org/wiki/Neutral_build"&gt;Nightly Builds&lt;/a&gt; ve Deploy'lar sırasında oluşturulan patikalardır. Bu patikalar kabul görmüş geliştirmeleri içerir.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;site :&lt;/span&gt; Projeye ait bilgileri içeren web sayfalarının bulunduğu yerdir. Özellikle Maven ile otomatik olarak oluşturulan raporları içerir.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;sandbox :&lt;/span&gt; Sandbox (kum havuzu) içerisinde her uygulama geliştiriciye ait klasörler bulunur. Bu klasörler içerisinde uygulama geliştiriciler yapacakları araştırmaları ve denemeleri burada depolar.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Versiyonlama Sistemi Yönetim Kuralları&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Aynı proje üzerinde 5 kişiden oluşan takımların geliştirme yaptığını düşünelim. Oluşabilecek kod çakışmalarını ve getireceği sorunları tahmin edebiliriz; kod çakışmaları, birbirlerinin kodlarını ezme, birim  ve entegrasyon testlerinden geçememe v.b..&lt;br /&gt;&lt;br /&gt;Elimizde Gövde (trunk) ve patikalar (branch) klasörleri ile ilgili katı kurallarımız olursa yaşanabilecek sorunları en aza indirgemiş olabiliriz.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Gövde (Trunk) Yönetimi&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Gövde'nin  özellikleri&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. Gövde (trunk) her zaman deploy edilebilir olmalı&lt;br /&gt;2. Sağlıklı (Stable) olmalı&lt;br /&gt;3. Üzerinde kod geliştirmesi gerçekleştirilmemeli&lt;br /&gt;4. Birim (Unit Test) ve entegrasyon (Integration Test) testlerinden geçmelidir&lt;br /&gt;5. Gövde Yöneticisi tarafından yönetilmelidir.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Gövde Yöneticisinin Görevleri&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. Nightly Build sonrası Gövde'nin sağlık durumunu sürekli takip etmelidir&lt;br /&gt;2. Testleri bozan kod aktarımlarında (merge), aktarımın hangi takım tarafından yapıldığını tespit etmelidir.&lt;br /&gt;3. Sorun tespit ederse hemen ilgili takımın lideri ile irtibata geçip hatalı kodu düzelttirmelidir.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Geliştirme Patikalarının (Branch) Özellikleri&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Gövde üzerinde kod geliştirilmesi yapılmayacaksa nerede yapılacak? Bunun için patikalar yardımımıza koşmaktadır. &lt;a href="http://agilesoftwaredevelopment.com/"&gt;Çevik süreçler&lt;/a&gt;de bir projenin planlama toplantılarında verilen Hikaye Puanları (Story Points) projenin kaç sprint'den oluşacağı ver her sprint'de hangi hikayelerin (Story) bulunacağı belirlenir. Belli büyüklükteki hikayeleri ise görevlere (Task) böleriz.&lt;br /&gt;&lt;br /&gt;İlgili proje için Gövde'den (trunk) bir Patika (branch) oluşturalım. Bir takım birden fazla uygulama geliştiriciden oluşursa ve projeye ait hikayeler paralel olarak geliştirilirse Gövde'de yaşadığımız sorunlarla Proje Patika'sında da karşılaşmayacak mıyız?&lt;br /&gt;&lt;br /&gt;Evet karşılaşacağız.Çözüm ne olacak peki?&lt;br /&gt;&lt;br /&gt;Çözüm 1: Takım içerisindeki tüm geliştiriciler tek bir hikayeye odaklanacak.&lt;br /&gt;Çözüm 2: Proje Patikasından (Project Branch) Hikaye Patikaları (Story Branch) oluşturulur, her hikaye kendisine ait patkida geliştirilir. Onaylanmış hikayeler Proje Patikasında birleştirilir.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Proje Patikasının Özellikleri&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. Gövde'den (Trunk) veya başka bir patikadan oluşturulurlar.&lt;br /&gt;2. Üzerinde sadece önceliği en yüksek hikayenin geliştirmesi yapılabilir veya her hikaye kendisine ait patikada geliştirilir.&lt;br /&gt;3. Takım içerisinden bir kişi Proje Patikasının yöneticisi olarak seçilmelidir.&lt;br /&gt;4. Üzerinde birim testler (Unit Test) çalıştırılmalıdır.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Proje Patikası Yöneticisinin Görevleri&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. Proje patikasının sağlıklı (stable) olmasını sağlar&lt;br /&gt;2. &lt;a href="http://en.wikipedia.org/wiki/Continuous_integration"&gt;Sürekli Entegrasyon&lt;/a&gt; (Continuous Integration) ile birim testlerin periyodik olarak çalıştırılmasını sağlar&lt;br /&gt;3. Hikaye patikalarından (Story Branch) gelen aktarımların (merge) düzgün yapıldığını kontrol eder&lt;br /&gt;4. Hatalı aktarımı yapan kişiyi uyarır, sorunun çözülmesini sağlar&lt;br /&gt;5. Kabul gören hikayelerin, Gövde'ye (Trunk) aktarımını gerçekleştirir.&lt;br /&gt;6. Belli aralıklarla Gövde'deki yeni aktarımları Proje Patikasına atkarmalıdır.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Kod Aktarımını İlk Yapan Kraldır&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Çevik takımların bulunduğu geliştirme ortamında takımların birbirlerinin kod aktarımlarını bozmaları kaçınılmazdır. En önemli kuralımız &lt;span style="font-weight: bold; color: rgb(204, 0, 0);"&gt;Gövde'nin (Trunk) her zaman deploy edilebilir bütün testlerden geçmiş olmasıdır&lt;/span&gt;. Bu kural dahilinde bir T2 takımı, tüm testlerden geçmiş bir T1 takımının aktarımını bozuyorsa o sorunu çözmek T2 takımının görevidir. Bu yüzden T1 takımını kral olarak ilan edebiliriz.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Kaynaklar&lt;/span&gt;&lt;br /&gt;1. InfoQ : &lt;a href="http://www.infoq.com/articles/agile-version-control"&gt;Version Control for Multiple Agile Teams&lt;/a&gt; : &lt;strong style="font-weight: normal;"&gt;&lt;a href="http://www.infoq.com/author/Henrik-Kniberg" class="editorlink"&gt;Henrik Kniberg&lt;/a&gt;&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-7039525414174541322?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/7039525414174541322/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=7039525414174541322' title='1 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/7039525414174541322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/7039525414174541322'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/01/cevik-takmlar-ve-versiyonlama-sistemi.html' title='Çevik Takımlar ve Versiyonlama Sistemi Kullanımı'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-1066970500621270864</id><published>2010-01-13T03:00:00.000-08:00</published><updated>2011-07-27T04:55:44.688-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='JAXB'/><category scheme='http://www.blogger.com/atom/ns#' term='XML'/><title type='text'>JAXB 2 VE HelloWorld</title><content type='html'>Java Architecture for XML Binding (JAXB), Java sınıfları ile XML dosyasını ilişkilendirip okuma ve yazma işlemlerini kolaylaştıran bir kütüphanedir. &lt;br /&gt;&lt;br /&gt;Eski Jaxb kullanımında öncelikle XML dosyasındaki verilerin tiplerini ve dosya yapısını tanımlayan bir şema oluşturmak gerekiyordu. Daha sonra JAXB paketi içerisindeki komutları kullanarak şema dosyasına göre ilgili Java yapılarının (sınıf, arayüz v.b.) oluşturulmasını sağlıyorduk.&lt;br /&gt;&lt;br /&gt;Yeni JAXB ile artık şema dosyası oluşturmak gerekmiyor. Tıpkı Hibernate-Annotation sisteminde olduğu gibi ilgili model sınıflarında annotation tanımlamaları yaparak XML dosyası üzerinde işlem gerçekleştirilebiliyor.&lt;br /&gt;&lt;br /&gt;JAXB kütüphanesinin 2.2 versiyonunu &lt;a href="https://jaxb.dev.java.net/2.2-ea/JAXB2_20090410.jar"&gt;https://jaxb.dev.java.net/2.2-ea/JAXB2_20090410.jar&lt;/a&gt; bağlantısı üzerinden indirebilirseniz. İndirdiğiniz Jar dosyasını Windows sistemlerde üzerine çift tıklayarak yada komut satırında &lt;br /&gt;&lt;br /&gt; java -jar JAXB2_20090410.jar&lt;br /&gt;&lt;br /&gt;komutunu çalıştırırak indirme işlemini gerçekleştirebilirsiniz.&lt;br /&gt;&lt;br /&gt;Şimdi gelin JAXB dünyasına bir “Hello World” diyelim.&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package org.jtpd.taner.jaxb.helloworld;&lt;br /&gt;&lt;br /&gt;import javax.xml.bind.annotation.XmlElement;&lt;br /&gt;import javax.xml.bind.annotation.XmlRootElement;&lt;br /&gt;import javax.xml.bind.annotation.XmlTransient;&lt;br /&gt;import javax.xml.bind.annotation.XmlType;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * @author Taner Diler&lt;br /&gt; *&lt;br /&gt; */&lt;br /&gt;@XmlRootElement(name="JTPD")&lt;br /&gt;@XmlType(name = "HelloWorld")&lt;br /&gt;public class HelloWorld {&lt;br /&gt;&lt;br /&gt; private String message = "Hello World";&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * @return the message&lt;br /&gt;  */&lt;br /&gt; @XmlElement(name="message")&lt;br /&gt; public String getMessage() {&lt;br /&gt;  return message;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * @param message the message to set&lt;br /&gt;  */&lt;br /&gt; public void setMessage(String message) {&lt;br /&gt;  this.message = message;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /* (non-Javadoc)&lt;br /&gt;  * @see java.lang.Object#toString()&lt;br /&gt;  */&lt;br /&gt; @Override&lt;br /&gt; public String toString() {&lt;br /&gt;  StringBuilder strb = new StringBuilder();&lt;br /&gt;  strb.append(super.toString()+"\n");&lt;br /&gt;  strb.append("\tHelloWorld.message = "+this.getMessage());&lt;br /&gt;  return strb.toString();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;XML dosyasına yazacağımız sınıf tanımlaması yukarıdaki gibidir. Gerekli XML annotationları ile sınıf bilgilerinin dosyaya ne şekilde yazılacağı ayarlanıyor.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;&lt;br /&gt;package org.jtpd.taner.jaxb.helloworld;&lt;br /&gt;&lt;br /&gt;import java.io.File;&lt;br /&gt;&lt;br /&gt;import javax.xml.bind.JAXBContext;&lt;br /&gt;import javax.xml.bind.JAXBException;&lt;br /&gt;import javax.xml.bind.Marshaller;&lt;br /&gt;import javax.xml.bind.Unmarshaller;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * @author Taner&lt;br /&gt; *&lt;br /&gt; */&lt;br /&gt;public class XMLManager {&lt;br /&gt; &lt;br /&gt; private static final String XMLFILE = "HelloWorld.xml";&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * read object from XML file&lt;br /&gt;  * @return {@link HelloWorld} object&lt;br /&gt;  * @throws JAXBException&lt;br /&gt;  */&lt;br /&gt; public HelloWorld readObject() throws JAXBException{&lt;br /&gt;  System.out.println("XML dosyasindan okuma yapiliyor.");&lt;br /&gt;  JAXBContext jc = JAXBContext.newInstance(HelloWorld.class);&lt;br /&gt;  Unmarshaller u = jc.createUnmarshaller();&lt;br /&gt;  HelloWorld hw = (HelloWorld) u.unmarshal(new File(XMLFILE));&lt;br /&gt;  return hw;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * write {@link HelloWorld} object to XML file&lt;br /&gt;  * @param hw&lt;br /&gt;  * @throws JAXBException&lt;br /&gt;  */&lt;br /&gt; public void writeObject(HelloWorld hw) throws JAXBException{&lt;br /&gt;  System.out.println("HelloWorld nesnesi XML dosyasina yaziliyor.");&lt;br /&gt;  JAXBContext jc = JAXBContext.newInstance(HelloWorld.class);&lt;br /&gt;  Marshaller m = jc.createMarshaller();&lt;br /&gt;  m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);&lt;br /&gt;  m.marshal(hw, new File(XMLFILE));&lt;br /&gt;  m.marshal(hw, System.out);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * @param args&lt;br /&gt;  * @throws JAXBException &lt;br /&gt;  */&lt;br /&gt; public static void main(String[] args) throws JAXBException {&lt;br /&gt;  HelloWorld hw = new HelloWorld();&lt;br /&gt;  XMLManager xm = new XMLManager();&lt;br /&gt;  &lt;br /&gt;  xm.writeObject(hw);&lt;br /&gt;  hw = xm.readObject();&lt;br /&gt;  System.out.println("\nOkunan HelloWorld nesnesi :");&lt;br /&gt;  System.out.println(hw.toString());&lt;br /&gt;  System.out.println("\nOkunan nesne içerisindeki mesaj degistirildi.");&lt;br /&gt;  hw.setMessage("Merhaba Dunya");&lt;br /&gt;  xm.writeObject(hw);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;XMLManager sınıfı HelloWorld sınıfına ait nesnenin XML dosyasına yazılması ve bu dosyadan okunması işini üstlenmiştir.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Uygulama çıktısı aşağıdaki gibidir:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;HelloWorld nesnesi XML dosyasina yaziliyor.&lt;br /&gt;&lt;br /&gt;&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;&lt;br /&gt;&lt;JTPD&gt;&lt;br /&gt;    &lt;message&gt;Hello World&lt;/message&gt;&lt;br /&gt;&lt;/JTPD&gt;&lt;br /&gt;&lt;br /&gt;XML dosyasindan okuma yapiliyor.&lt;br /&gt;&lt;br /&gt;Okunan HelloWorld nesnesi :&lt;br /&gt;org.jtpd.taner.jaxb.helloworld.HelloWorld@914f6a&lt;br /&gt; HelloWorld.message = Hello World&lt;br /&gt;&lt;br /&gt;Okunan nesne içerisindeki mesaj degistirildi.&lt;br /&gt;HelloWorld nesnesi XML dosyasina yaziliyor.&lt;br /&gt;&lt;br /&gt;&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;&lt;br /&gt;&lt;JTPD&gt;&lt;br /&gt;    &lt;message&gt;Merhaba Dunya&lt;/message&gt;&lt;br /&gt;&lt;/JTPD&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;KAYNAKLAR&lt;br /&gt;&lt;a href=" http://en.wikipedia.org/wiki/JAXB"&gt;&lt;br /&gt;http://en.wikipedia.org/wiki/JAXB&lt;/a&gt;&lt;br /&gt;&lt;a href="https://jaxb.dev.java.net/"&gt;https://jaxb.dev.java.net/&lt;/a&gt; &lt;br /&gt;&lt;a href="http://technology.amis.nl/blog/?p=2046"&gt;http://technology.amis.nl/blog/?p=2046&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-1066970500621270864?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/1066970500621270864/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=1066970500621270864' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/1066970500621270864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/1066970500621270864'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/01/jaxb-2-ve-helloworld.html' title='JAXB 2 VE HelloWorld'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-8845436702592180019</id><published>2010-01-13T02:53:00.000-08:00</published><updated>2011-07-27T04:57:18.179-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='versiyonlama sistemi'/><title type='text'>Subversion Kurulumu ve Apache Http Sunucusu Entegrasyonu</title><content type='html'>&lt;b&gt;&lt;span style="font-size:100%;"&gt;1. Versiyon Kontrol Sistemleri&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Büyük olsun yada küçük olsun tüm şirketlerde, şirket içerisindeki dökümanların akışının ve arşivlenmesinin kontrolü için kullanılan bir sistem vardır. Bu sistem bilgisayar ortamında çalışan bir programdan yada belgeleri raflarda arşivleyen ve belge akışını sağlayan kişilerden oluşabilir.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Bu amaçla kullanılan bilgisayar programlarına en çok yazılım şirketlerinde rastalanmaktadır. Çünkü yazılımcılar gün içinde sürekli kodlarda ufak değişiklikler yapmaktadırlar. Gerektiğinde dosyaları eski tarihteki versiyonlarına geri döndürmektedirler. Bunları yaparken diğer yazılımcıların etkilenmemesi gerekmektedir. İşte bu anda devreye giren bu programlar bir dosya üzerinde farklı kullanıcılar tarafından aynı anda yapılan değişikliklerin birbirini yok etmesini engeller.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Günümüzde yazılım şirketlerinde çoğunlukla CVS (Concurrent Versions System), Subversion ve MS SourceSafe sistemleri kullanılmaktadır. Özellikle CVS sistemi açık kaynak kodlu (Open Source) bir proje olduğu için açık kaynak kodlu olarak geliştirilen projelerde kullanılmaktadır. Bu tür projelere &lt;a title="http://sourceforge.net/" href="http://sourceforge.net/"&gt;&lt;span style="color: blue;"&gt;http://sourceforge.net/&lt;/span&gt;&lt;/a&gt;adresinden ulaşabilirsiniz.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:100%;"&gt;2. Subversion Sistemi&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;2000 yılından önce Collabnet firması ( &lt;a href="http://www.collab.net/"&gt;&lt;span style="color: blue;"&gt;http://www.collab.net/&lt;/span&gt;&lt;/a&gt;) CVS'e alternatif bir versiyonlama sistemi geliştirmeye kararverir. İlk geliştirilen SourceCast sistemi temelde CVS sistemini kullanmaktaydı. Bu nedenle CVS sisteminde var olan kısıtlamalar bu yeni sistemde de görüldü. Bunun üzerine Collabnet firması tarafından CVS'den daha iyi bir sistem geliştirilmeye karar verildi.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;14 aylık kodlama döneminden sonra geliştirilen Subversion sistemi 31 Ağustos 2001 tarihinde hizmet vermeye başladı. Açık kaynak kodlu (Open Source) olan Subversion sistemi ücretsiz olarak indirilebilir, kodlarında istenilen değişiklik yapılabilir.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:100%;"&gt;3. Subversion Sisteminin Özellikleri&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;ul type="disc"&gt;&lt;li class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:100%;"&gt;Klasör Versiyonlama &lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:100%;"&gt;CVS sistemi sadece dosyaları versiyonlar. Subversion sistemi ise dosyalarla birlikte klasörlerinde versiyonlanmasını sağlar.&lt;/span&gt;  &lt;ul type="disc"&gt;&lt;li class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:100%;"&gt;Atomik Güncelleme : &lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:100%;"&gt;Yapılan değişikliler ya tümü birden gönderilir ya da azar azar gönderilir. Bu özellik uygulama geliştiricilerin yapılan değişiklikleri bir yığın olarak sunucuya göndermesini sağlar. Böylece değişikliklerin sadece bir bölümünün gönderilmesinden kaynaklanan problemlerin oluşması engellenmiş olunur.&lt;/span&gt;  &lt;ul type="disc"&gt;&lt;li class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:100%;"&gt;Versiyon Bilgileri: &lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:100%;"&gt;Subversion sisteminde her dosya ve klasör kendisine ait “ &lt;b&gt;anahtar-değer &lt;/b&gt;” çiftlerinden oluşan özellikler içermektedir. Bu özellikler, dosya içerikleri gibi versiyonlama işlemine tabi tutulabilir.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt; &lt;ul type="disc"&gt;&lt;li class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:100%;"&gt;Ağ Üzerinden Erişim &lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:100%;"&gt;Subversion sistemi Apache HTTP sunucusuna ek bir modül olarak eklenebilir. Bu özellik Subversion sistemine kararlılık ve farklı platformlarda çalışabilirlilik açısında büyük avantaj kazandırmaktadır. Böylece Subversion sistemi, entegre edildiği sistemin sağladığı güvenlik, kullanıcı kontrolü gibi servisleri kullanabilir duruma gelir.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt; &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:100%;"&gt;4. Subversion Kurulumu &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Subversion sisteminin kurulumunu Windows işletim sistemi üzerinde gerçekleştireceğiz. Bunun için &lt;a href="http://subversion.tigris.org/"&gt;&lt;span style="color: blue;"&gt;http://subversion.tigris.org/&lt;/span&gt;&lt;/a&gt; adresi üzerinden svn paketini indirmeniz gerekmektedir. İlgili Windows Binary paketini istediğiniz dağıtıcıya göre indirebilirsiniz. İndirme işlemi bittikten sonra kurulum dosyasını çalıştıralım. Önümüzde kurulum adımlarını gösteren pencere çıkacaktır. Burada gerekli işlemleri yaptıktan ve Subversion sistemini kuracağımız dizini belirttikten sonra kurulum gerçekleşecektir. Kurulumu test etmek için “Command Prompt” da&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;table class="MsoNormalTable zeroBorder" style="width: 100%; font-weight: bold;" width="100%" border="0" cellpadding="0" cellspacing="4"&gt;  &lt;tbody&gt;&lt;tr&gt;   &lt;td style="background: rgb(204, 204, 204) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;svn   --version &lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;yazalım. Çalıştırdığımızda aşağıdaki gibi bir sonuç alırız. &lt;/span&gt;&lt;/p&gt;&lt;div style="text-align: center;"&gt;&lt;div id="kbm_" style="text-align: center;"&gt;&lt;img style="width: 592px; height: 263px;" src="http://docs.google.com/File?id=dcwqjq5f_35gjvqxzc8_b" /&gt;&lt;/div&gt;&lt;/div&gt;   &lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;  &lt;p class="MsoNormal" style="text-align: center;" align="center"&gt;&lt;span style="font-size:100%;"&gt;Şekil – 1 : Subversion sistemi &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Subversion sistemi çalıştığına göre kaynak kodların ve versiyonlama işlemi ile ilgili bilgilerin tutulacağı bir tane depo (repository) oluşturalım. Bunun için aşağıdaki gibi bir komut çalıştırmamız gerekiyor.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;table class="MsoNormalTable zeroBorder" style="width: 100%; font-weight: bold;" width="100%" border="0" cellpadding="0" cellspacing="4"&gt;  &lt;tbody&gt;&lt;tr&gt;   &lt;td style="background: rgb(204, 204, 204) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;svnadmin   create     c:\repository &lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Bu işlem sonrasında Şekil-2 deki gibi dizin yapısı oluşur. &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;div id="wcif" style="text-align: center;"&gt;&lt;img style="width: 120px; height: 152px;" src="http://docs.google.com/File?id=dcwqjq5f_36d5d4kccz_b" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:100%;"&gt; Şekil-2 : “svnadmin create” komutunun etkisi &lt;/span&gt;&lt;/div&gt;  &lt;p class="MsoNormal" style="text-align: center;" align="center"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Şimdi sıra var olan bir projeyi depoya (repository) eklemeye geldi. “C:\TEMP” dizini altında &lt;i&gt;file_1.txt &lt;/i&gt;, &lt;i&gt;file_2.txt &lt;/i&gt;, &lt;i&gt;file_3.txt &lt;/i&gt;ve &lt;i&gt;file_4.txt &lt;/i&gt;dosyalarından oluşan “ &lt;b&gt;project1” &lt;/b&gt;isimli projeyi depoya ekleyelim. Proje ekleme işlemleri için “ &lt;b&gt;svn import &lt;/b&gt;“ komutu kullanılır.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;table class="MsoNormalTable zeroBorder" style="width: 100%; font-weight: bold;" width="100%" border="0" cellpadding="0" cellspacing="4"&gt;  &lt;tbody&gt;&lt;tr&gt;   &lt;td style="background: rgb(204, 204, 204) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;svn   import     --message " "   c:\temp\project1     file:///c:/repository/project1 &lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Komut sonucunda aşağıdaki ekran karşımıza gelir. &lt;/span&gt;&lt;/p&gt;  &lt;p style="text-align: center;" class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt; &lt;/span&gt;&lt;img style="width: 608px; height: 99px;" src="http://docs.google.com/File?id=dcwqjq5f_37fptdd5kn_b" /&gt;&lt;/p&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:100%;"&gt;Şekil -3 : Var olan bir projenin depoya (repository) eklenmesi &lt;/span&gt;&lt;/div&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Subversion sistemi yeni oluşturulmuş bir depoya (repository) dosya ya da klasör eklendiğinde değişiklik (revision) numarasını 1 yapar. Daha sonra yapılacak olan değişiklikler sonucu değişiklik (revision) değeri artacaktır. (Değişiklik değeri ile ilgili daha sonraki yazılarda detaylı şekilde değinilecektir.) Subversion dosyalar üzerinde yapılmış olan değişiklikleri değişiklik (revision) değerine göre kontol eder. &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;“Project1” isimli projenin depoya (repository) eklenip eklenmediğine bakalım.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;table class="MsoNormalTable zeroBorder" style="width: 100%; font-weight: bold;" width="100%" border="0" cellpadding="0" cellspacing="4"&gt;  &lt;tbody&gt;&lt;tr&gt;   &lt;td style="background: rgb(204, 204, 204) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;svnlook     tree   c:\repository &lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;komutunu çalıştırdığımız zaman Şekil-4'de ki gibi depoya (repository) eklenenleri görebiliriz. &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt; &lt;div id="qi6:" style="text-align: center;"&gt;&lt;img style="width: 256px; height: 97px;" src="http://docs.google.com/File?id=dcwqjq5f_38fwb872gb_b" /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="text-align: center;" align="center"&gt;&lt;span style="font-size:100%;"&gt;Şeklik - 4 : Depoda (repository) var olanların listesi &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size:100%;"&gt;5. Apache HTTP Server'ının Kurulum&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Subversion sisteminin Apache Server ile entegrasyonunu Apache Server'ın 2.0.49 versiyonunda gerçekleştireceğiz. Önce &lt;a href="http://httpd.apache.org/download.cgi"&gt;&lt;span style="color: blue;"&gt;http://httpd.apache.org/download.cgi&lt;/span&gt;&lt;/a&gt;sitesinden Windows işletim sistemi için ilgili Apache Server'ı indirelim. Kurulum programını çalıştırarak kurulumu gerçekleştirdikten sonra &lt;b&gt;&lt;i&gt;“...\Apache Group\Apache2\conf” &lt;/i&gt;&lt;/b&gt;dizini altında bulunan &lt;b&gt;&lt;i&gt;httpd.conf &lt;/i&gt;&lt;/b&gt;dosyasında birkaç değişiklik yapmamız gerekiyor.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Httpd.conf dosyasında aşağıdaki satırın başındaki ‘ # ' işaretini kaldırarak satırı aktif yapalım.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;i&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;#LoadModule dav_module modules/mod_dav.so &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Bu satırdan sonra yeni bir satıra&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;i&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;LoadModule dav_svn_module modules/mod_dav_svn.so &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;ekleyelim.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Şimdi Subversion sistemini kurduğumuz dizindeki “&lt;b&gt;httpd&lt;/b&gt;” klasörü içerisindeki “&lt;b&gt;mod_dav_svn.so&lt;/b&gt;” dosyasını &lt;b&gt;&lt;i&gt;“...\Apache Group\Apache2\modules” &lt;/i&gt;&lt;/b&gt;dizinine kopyalayalım.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;“ httpd.conf ” dosyasısının en sonuna&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;table class="MsoNormalTable zeroBorder" style="width: 100%; font-weight: bold;" width="100%" border="0" cellpadding="0" cellspacing="4"&gt;  &lt;tbody&gt;&lt;tr&gt;   &lt;td style="background: rgb(204, 204, 204) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;location&gt; &lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;    DAV svn &lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;    SVNPath c:/repository/ &lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;&lt;/location&gt; &lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;tanımlamasını yapalım ve dosyayı kaydedelim. &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Apache Server'ını başlattıktan sonra bir web görüntüleyicisinde (web browser) &lt;a href="http://sunucu_ismi/repository"&gt;&lt;span style="color: blue;"&gt;http://sunucu_ismi/repository&lt;/span&gt;&lt;/a&gt;bağlantısını yazdığımızda Şekil-5 teki gibi depoya (repository) eklenenleri dizin yapısı şeklinde görüntüler.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="font-size:100%;"&gt; &lt;/span&gt;  &lt;div id="z.kc" style="text-align: center;"&gt;&lt;img style="width: 339px; height: 171px;" src="http://docs.google.com/File?id=dcwqjq5f_39359qpbmc_b" /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:100%;"&gt;Şekil-5 Depodakilerin (repository) görüntülenmesi&lt;/span&gt;&lt;/div&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Subversion sistemi ile Apache Http sunucusunu entegrasyonunu gerçekleştirdik.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span style="font-size:100%;"&gt;6. Projeyi Kullanıcı Makinasına İndirmek&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Depodaki bir projeye dahil olmak için önce bu projenin kullanıcı makinasına depodan çekilmesi gerekiyor. Bunun için “ &lt;b&gt;&lt;i&gt;svn checkout ... &lt;/i&gt;&lt;/b&gt;” komutu kullanılır. Bu işlemi http üzerinden gerçekleştirmek için aşağıdaki komutu çalıştıralım.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;table class="MsoNormalTable zeroBorder" style="width: 100%; font-weight: bold;" width="100%" border="0" cellpadding="0" cellspacing="4"&gt;  &lt;tbody&gt;&lt;tr&gt;   &lt;td style="background: rgb(204, 204, 204) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;   &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;svn     checkout   http://localhost/repository/project1     c:\pro_1 &lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Burada “ &lt;i&gt;&lt;a href="http://localhost/repository/project1"&gt;&lt;span style="color: blue;"&gt;http://localhost/repository/project1&lt;/span&gt;&lt;/a&gt;&lt;/i&gt;“ adresindeki dosya ve dizin yapısını “ &lt;b&gt;&lt;i&gt;c:\pro_1 &lt;/i&gt;&lt;/b&gt;” altına kopyalar.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;div id="auq5" style="text-align: center;"&gt;&lt;div id="tf8v" style="text-align: center;"&gt;&lt;img style="width: 543px; height: 94px;" src="http://docs.google.com/File?id=dcwqjq5f_42dwd476g2_b" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:100%;"&gt;Şekil-6 Depodaki projenin kopyalanması &lt;/span&gt;&lt;/div&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Buradaki A harfleri ilgili dosyanın eklendiğini göstermektedir. &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Dizin yapısı Şekil-7 deki gibidir. &lt;div id="whzh" style="text-align: center;"&gt;&lt;img style="width: 157px; height: 176px;" src="http://docs.google.com/File?id=dcwqjq5f_41fc9c99d8_b" /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="text-align: center;" align="center"&gt;&lt;span style="font-size:100%;"&gt;Şekil-7 Kullanıcı makinada oluşan dizin yapısı&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;Projeyi kopyaladığımızda otomatik olarak “ &lt;b&gt;.svn &lt;/b&gt;” klasörü oluşur. Bu klasör içerisinde her değişiklik (revision) numarasına ait değişiklikler bulunmaktadır. Ayrıca kullanıcının yaptığı yerel değişiklikler burada saklanmaktadır. Kullanıcı bilgisayar ağına bağlı olmadığı zamanlar yaptığı değişiklikleri, bilgisayar ağına bağlandığında depoya (repository) yükleyebilir. Bu esnada gerekli tüm bilgiler “.svn” içerisinden alınmaktadır. &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-8845436702592180019?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/8845436702592180019/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=8845436702592180019' title='1 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/8845436702592180019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/8845436702592180019'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/01/subversion-kurulumu-ve-apache-http.html' title='Subversion Kurulumu ve Apache Http Sunucusu Entegrasyonu'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-7155929675397884312</id><published>2010-01-07T03:43:00.000-08:00</published><updated>2011-07-27T04:53:21.962-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='yaşam'/><title type='text'>Hayatınızı Değiştirecek 62 Öneri</title><content type='html'>LinkedIn üzerinden &lt;a href="http://ferruh.mavituna.com"&gt;blog sayfasına&lt;/a&gt; ulaştığım &lt;a href="http://uk.linkedin.com/in/fmavituna"&gt;Feruh Mavituna&lt;/a&gt; tarafından yazılmış kendimizi geliştirirken, zamanı planlarken, proje geliştirirken yapabileceğimiz 62 güzel öneriye &lt;a href="http://ferruh.mavituna.com/hayatinizi-degistirecek-oneri-oku/"&gt;buradan&lt;/a&gt; ulaşabilirsiniz. Bu önerilerden bazıları:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Kısayolları öğrenin, &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Bilmediğinizi bilin&lt;/strong&gt;, anlayın ve itiraf edin, &lt;/li&gt;&lt;li&gt;Bir blog tutun, sadece kendinize özel olabilir ama bir blog tutun, &lt;/li&gt;&lt;li&gt;Bulunduğunuz alandaki blogları takip edin, &lt;/li&gt;&lt;li&gt;RSS Reader kullanın, &lt;/li&gt;&lt;li&gt;E-maillarınızı 10 dk. da bir kontrol etmeyin, e-mail programınızı kapalı tutun ve iki saatte bir ya da benzer vakitlerde açıp kontrol edin,&lt;/li&gt;&lt;li&gt;Aynı anda birden fazla iş yapmayın (&lt;em&gt;Multi-Threading&lt;/em&gt;), &lt;strong&gt;Odağınızı koruyun&lt;/strong&gt;, &lt;/li&gt;&lt;li&gt;Eğer projeniz yapılmışın daha iyisi veya tamamen yeni bir şey degilse o &lt;strong&gt;projeyi yapmayın,&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;CV - Özgeçmişinizi her zaman güncel tutun, Kendinizi bulunduğunuz yerde çalışma zorunluluğunda hissetmeyin, alternatifleriniz olduğunu bilin, &lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-7155929675397884312?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/7155929675397884312/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=7155929675397884312' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/7155929675397884312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/7155929675397884312'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2010/01/hayatnz-degistirecek-62-oneri.html' title='Hayatınızı Değiştirecek 62 Öneri'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-2035820063771047076</id><published>2009-12-25T08:02:00.001-08:00</published><updated>2009-12-27T08:11:07.504-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Seminer'/><category scheme='http://www.blogger.com/atom/ns#' term='Java Eğitimi'/><title type='text'>19-20 Aralık 2009 Eskişehir'in Ardından</title><content type='html'>Haziran aylarında Osmangazi Üni. IEEE Öğrenci Kolu Başkanı Alper Şenyurt bizimle iletişime geçerek iki günlük bir Java etklinliği yapmak istediklerini söyledi. Sınav ve tatil nedeni ile  Java Seminer'ini 19-20 Aralık tarihinde yapmamızın daha uygun olduğunu kararlaştırdık.&lt;br /&gt;&lt;br /&gt;19 Aralık Cumartesi günü sabah 9 da Temel Java ile seminerimize başladık. Tipler, Döngü/Koşul yapıları, Diziler, Torbalar ve Java ile Nesneye Yönelik Programlama konularından bahsettim.&lt;br /&gt;Öğleden sonra ise katılım sayısı 100 kişi civarı oldu. Öğleden sonraki konularımız ise JSP&amp;amp;Servlet, Yazılım Geliştirme Ortamı (Versiyonlama Sistemleri, TDD, Veritabanı Versiyonlanması, ANT, Maven, Continous Integration ve Web Framework) ve Tasarım Kalıplarıydı.&lt;br /&gt;&lt;br /&gt;&lt;div id="o1_v" style="text-align: left;"&gt;&lt;img style="width: 648px; height: 486px;" src="http://docs.google.com/File?id=dcwqjq5f_21cczk9zhr_b" /&gt;&lt;div id="yk_j" style="text-align: left;"&gt;&lt;img style="width: 648px; height: 486px;" src="http://docs.google.com/File?id=dcwqjq5f_22v73dr3g9_b" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Ertesi gün lab çalışmalarımız vardı. İki büyük gerçek yaşam senaryosu ile lab çalışmasına katılanları biraz zorladık. Bu örneklerdeki amacımız, Sınıf, Nesne, Kalıtım, Dahili Sınıflar, Döngü/ŞartYapıları, Statik Yapılar ve Nesneye Yönelik Programlama pratiğinin kazandırılmasıydı.&lt;br /&gt;&lt;br /&gt;&lt;div id="eshe" style="text-align: left;"&gt;&lt;img style="width: 648px; height: 486px;" src="http://docs.google.com/File?id=dcwqjq5f_23ck8bqcdm_b" /&gt;&lt;div id="k7x5" style="text-align: left;"&gt;&lt;img style="width: 648px; height: 486px;" src="http://docs.google.com/File?id=dcwqjq5f_24d3fnzqdn_b" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;Herşeyiyle güzel bir etkinlik oldu. Gösterdikleri misafirperverlikleriyle Osmangazi IEEE Öğrenci Kolu üyelerine ve etkinliğe katılan herkese teşekkür ederim.&lt;br /&gt;&lt;br /&gt;Bir sonraki etkinlikte  görüşmek üzere.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-2035820063771047076?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/2035820063771047076/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=2035820063771047076' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/2035820063771047076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/2035820063771047076'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2009/12/19-20-aralk-2009-eskisehirin-ardndan.html' title='19-20 Aralık 2009 Eskişehir&apos;in Ardından'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-5820922691652170372</id><published>2009-12-22T03:19:00.000-08:00</published><updated>2011-07-27T04:56:24.861-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='versiyonlama sistemi'/><category scheme='http://www.blogger.com/atom/ns#' term='veritabanı'/><title type='text'>Liquibase - Veritabanı Versiyonlama Sistemi</title><content type='html'>Proje süresince karşılaşılacak sorunların erken tespit edilmesi ve bunlara önceden çözüm bulunması, uygun geliştirme ortamının oluşturulması ile mümkündür. Bir proje geliştirme ortamının olmazsa olmazlarından biri kod versiyonlama sistemleridir. Proje bir kişi tarafından bile geliştiriliyor olsa versiyonlama sisteminin kullanılması ve bunun başka bir sunucu üzerinden hizmet vermesi kodların güvende olmasını sağlar. Ayrıca farklı lokasyonlarda bulunan takım elemanları arasında kod değişikliklerinin takibi kod versiyonlama sistemi tarafından da gerçekleşecektir.&lt;br /&gt;&lt;br /&gt;Kodlarımızı güvence altına aldık. Yapılan ufak bir değişiklik diğer kullanıcılara aktarılacağı da garantilendi. Peki veritabanındaki verilerde ve şemada yapılan değişikliklere ne olacak? Açık kaynak kodlu olarak geliştirilen yazılımlarda test ve geliştirme sürecinde geliştiricilerin kendilerine ait veritabanı bulunur. Bir kişi tarafından yapılan değişiklik diğerleri tarafından görülmeli ve hemen kendi veritabanlarına uygulanmalıdır. Bu değişiklikler insan gücüyle (mail, telefon v.b.) paylaştırılabilir. Mail üzerinden yapılan haberleşme ve elle yapılan güncellemelerde bir yerden sonra takip zorlaşacaktır.&lt;br /&gt;&lt;br /&gt;Peki bu veritabanı değişikliklerin güncellenmesini nasıl otomatik hale getireceğiz? Geçmişini nasıl tutacağız?&lt;br /&gt;&lt;br /&gt;Veritabanı şemasında yapılabilecek değişikliklerin (database refactorings) listesine http://www.agiledata.org/ üzerinden ulaşabilirsiniz.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.liquibase.org"&gt;Liquibase&lt;/a&gt; ile bu işleri gerçekleştirebiliriz.&lt;br /&gt;&lt;br /&gt;1. Yapılan bütün değişiklikleri SQL, SQL Dosyası veya Liquibase'e özel XML tanımları ile liquibase-changelog.xml dosyası üzerinde kaydedebiliriz.&lt;br /&gt;2. Güncellemeleri geri alma (Update rollbacks)&lt;br /&gt;3. Değişikliklerin koşullara bağlanması&lt;br /&gt;4. Otomatik olarak güncelleme&lt;br /&gt;&lt;br /&gt;Liquibase, bağlandığı veritabanı içerisinde DATABASECHANGELOG ve DATABASECHANGELOGLOCK tablolarını otomatik olarak oluşturur. Değişiklikleri güncellediğinizde önce DATABASECHANGELOCK tablosuna kayıt atar ve XML dosyasındaki değişiklik kümelerinden (CHANGESET) CHECKSUM oluşturur ve DATABASECHANGELOG dosyasına ilgili kaydı atar.&lt;br /&gt;&lt;br /&gt;liquibase-changelog.xml&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;br /&gt;&lt;databaseChangeLog&lt;br /&gt;        xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.8"&lt;br /&gt;        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.8&lt;br /&gt;        http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.8.xsd"&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;changeSet author="tdiler" id="TSS-1" runOnChange="false"&gt;&lt;br /&gt;        &lt;comment&gt;veritabanini ve tablolari olusturan sql&lt;/comment&gt;&lt;br /&gt;        &lt;sqlFile path="src/main/liquibase/TSS-1.sql"/&gt;&lt;br /&gt;    &lt;/changeSet&gt;&lt;br /&gt;    &lt;changeSet author="tdiler" id="TSS-2" runOnChange="false"&gt;&lt;br /&gt;        &lt;comment&gt;Kurum ile Sehir tablosu FK yapildi&lt;/comment&gt;&lt;br /&gt;        &lt;sql&gt;&lt;br /&gt;     ALTER TABLE `tusside`.`kurum` CHANGE COLUMN `sehir` `sehir_id` INT(11) DEFAULT NULL,&lt;br /&gt;   ADD CONSTRAINT `FK_kurum_sehir` FOREIGN KEY `FK_kurum_sehir` (`sehir_id`)&lt;br /&gt;      REFERENCES `sehir` (`id`)&lt;br /&gt;      ON DELETE RESTRICT&lt;br /&gt;      ON UPDATE RESTRICT;&lt;br /&gt;        &lt;/sql&gt;&lt;br /&gt;    &lt;/changeSet&gt; &lt;br /&gt;&lt;/databaseChangeLog&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Oluşan DATABASECHANGELOG tablosu : &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_9vaXx_lumNA/SzC0sXR4-6I/AAAAAAAAAHM/pAxODXB1Jtk/s1600-h/databasechangelog.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_9vaXx_lumNA/SzC0sXR4-6I/AAAAAAAAAHM/pAxODXB1Jtk/s320/databasechangelog.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5418029025983003554" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.liquibase.org/"&gt;Maven&lt;/a&gt; entegrasyonu ile veritabanı değişikliklerinin yönetimi daha kolay hale gelmektedir. Bunun için pom.xml'de :&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&lt;build&gt;&lt;br /&gt;   &lt;plugin&gt;&lt;br /&gt;    &lt;groupId&gt;org.liquibase&lt;/groupId&gt;&lt;br /&gt;    &lt;artifactId&gt;liquibase-plugin&lt;/artifactId&gt;&lt;br /&gt;    &lt;version&gt;1.9.3.0&lt;/version&gt;&lt;br /&gt;    &lt;configuration&gt;&lt;br /&gt;     &lt;changeLogFile&gt;src/main/liquibase/liquibase-changelog.xml&lt;/changeLogFile&gt;&lt;br /&gt;     &lt;driver&gt;com.mysql.jdbc.Driver&lt;/driver&gt;&lt;br /&gt;     &lt;url&gt;jdbc:mysql://db.jtpd.gov.tr:3306/jtpd?characterEncoding=UTF-8&lt;/url&gt;&lt;br /&gt;     &lt;username&gt;liquibase&lt;/username&gt;&lt;br /&gt;     &lt;password&gt;liquibase1234&lt;/password&gt;&lt;br /&gt;     &lt;useUnicode&gt;true&lt;/useUnicode&gt;&lt;br /&gt;     &lt;characterEncoding&gt;UTF-8&lt;/characterEncoding&gt;&lt;br /&gt;     &lt;promptOnNonLocalDatabase&gt;false&lt;/promptOnNonLocalDatabase&gt;&lt;br /&gt;    &lt;/configuration&gt;&lt;br /&gt;    &lt;executions&gt;&lt;br /&gt;     &lt;execution&gt;&lt;br /&gt;      &lt;phase&gt;process-resources&lt;/phase&gt;&lt;br /&gt;      &lt;goals&gt;&lt;br /&gt;       &lt;goal&gt;update&lt;/goal&gt;&lt;br /&gt;      &lt;/goals&gt;&lt;br /&gt;     &lt;/execution&gt;&lt;br /&gt;    &lt;/executions&gt;&lt;br /&gt;    &lt;dependencies&gt;&lt;br /&gt;     &lt;dependency&gt;&lt;br /&gt;      &lt;groupId&gt;mysql&lt;/groupId&gt;&lt;br /&gt;      &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;&lt;br /&gt;      &lt;version&gt;5.1.6&lt;/version&gt;&lt;br /&gt;     &lt;/dependency&gt;&lt;br /&gt;    &lt;/dependencies&gt;&lt;br /&gt;   &lt;/plugin&gt;&lt;br /&gt;&lt;/build&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Böylelikle maven'in process-resources safhasında liquibase otomatik olarak çalışacaktır.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-5820922691652170372?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/5820922691652170372/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=5820922691652170372' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/5820922691652170372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/5820922691652170372'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2009/12/liquibase-veritaban-versiyonlama.html' title='Liquibase - Veritabanı Versiyonlama Sistemi'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_9vaXx_lumNA/SzC0sXR4-6I/AAAAAAAAAHM/pAxODXB1Jtk/s72-c/databasechangelog.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-4902325380430148461</id><published>2009-12-15T07:39:00.000-08:00</published><updated>2009-12-21T06:35:27.946-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='shortcuts'/><title type='text'>Eclipse ve Hayat Kurtaran KısaYol Tuşları</title><content type='html'>Bence bir programcı 10 Parmak klavye kullanabilmeli ve kullandığı editör veya sistemin kısa yollarını bilmelidir. Bu iş tıpkı Unix/Linux'de Siyah Ekran'da çalışmak gibi... Vi editörünü nerdeyse herkes kullanmak zorunda kalmıştır. KısaYol tuşlarını bilmeden Vi editörünü kullanamazsınız.&lt;br /&gt;&lt;br /&gt;7 yıldır Eclipse ile Java uygulamaları geliştiriyorum. Bana sunduğu kolaylıklar, plugin desteği ve düzeni açısından her zaman tercihim olmuştur. Kısayol tuşlarını kullanmak ise ayrı bir zevk ve gerçekten havalı oluyor.&lt;br /&gt;&lt;br /&gt;Eclipse'de kullandığım kısa yol tuşlarını sizinle paylaşmak istiyorum.&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;Kısa Yol&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Açıklaması&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;CTRL+SHIFT+O&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Açık olan Java Editörü'nde paket importlarını düzenler&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;CTRL+O&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Java Editöründeki öğeleri (değişken, yordam...) listeler&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;CTRL+2 R&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Toplu olarak değişkenin kullanıldığı yerlerde değişken ismini değiştirir&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;CTRL+2 F&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Çağrılan yordamdan dönen değeri tutacak global referans tanımlar&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;CTRL+2 L&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Çağrılan yordamdan dönen değeri tutacak lokal referans tanımlar&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;ALT+SHIFT+S&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Java Editörüne sağ tıklandığında açılan Kısayol Menüsünü (Context Menu) açar&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;ALT+SHIFT+S R&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Otomatik olarak Get/Set yordamı oluşturulacak değişkenlerin seçildiği pencereyi açar&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;ALT+SHIFT+S V&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Ana sınıf (Super Class) veya Arayüzden (Interface) ezilecek (Override) methodların seçildiği pencereyi açar &lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;ALT+SHIFT+S C&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Süper yapının yapılandırıcılarını (Constructors) ezen yapılandırıcı oluşturma penceresini açar&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;ALT+SHIFT+S C&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Değişkenleri seçerek yapılandırıcı oluşturabileceğim pencereyi açar&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;ALT+SHIFT+S F&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Java kodlarını formatlar&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;CTRL+SHIFT+F&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Java kodlarını formatlar&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;ALT+SHIFT+S T&lt;/b&gt;&lt;/div&gt;&lt;div&gt;İmlecin (Cursor) üzerinde bulunduğu yapı için uygun JavaDoc girişini yapar&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;ALT+SHIFT+J&lt;/b&gt;&lt;/div&gt;&lt;div&gt;İmlecin (Cursor) üzerinde bulunduğu yapı için uygun JavaDoc girişini yapar&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;ALT+SHIFT+T&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Refactoring kısayol menüsünü açar&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;ALT+SHIFT+T U&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Arayüze (Interface) tanımı çıkarılacak yordamların seçildiği pencereyi açar&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;CTRL+SHIFT+G&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Proje içerisinde imlecin bulunduğu yapıyı (özellik, yordam, sınıf v.b.) kullanan yerleri bulur&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;CTRL+M&lt;/b&gt;&lt;/div&gt;&lt;div&gt;İlgili editörü büyütür/küçültür&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;CTRL+SHIFT+W&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Açık bütün editörleri kapatır&lt;/div&gt;&lt;br /&gt;&lt;div style="float:left; width: 150px;"&gt;&lt;b&gt;F3&lt;/b&gt;&lt;/div&gt;&lt;div&gt;İmlecin bulunduğu yapının tanımını açar&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-4902325380430148461?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/4902325380430148461/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=4902325380430148461' title='3 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/4902325380430148461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/4902325380430148461'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2009/12/eclipse-ve-hayat-kurtaran-ksayol-tuslar.html' title='Eclipse ve Hayat Kurtaran KısaYol Tuşları'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-4356767573717820562</id><published>2009-12-13T04:24:00.000-08:00</published><updated>2009-12-13T04:48:09.100-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Applet'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Physics'/><title type='text'>Fizik için Java Applet'leri</title><content type='html'>&lt;a href="http://www.phy.ntnu.edu.tw/english/"&gt;Tayvan Üni. Fizik Bölümü&lt;/a&gt; öğrencileri tarafından geliştirilen Fizik Kanunları'na ait Java Applet uygulamarına &lt;a href="http://www.phy.ntnu.edu.tw/ntnujava/index.php#2"&gt;buradan&lt;/a&gt; ulaşabilirsiniz.&lt;br /&gt;&lt;br /&gt;Uygulamardan bazı örnekler : &lt;br /&gt;&lt;br /&gt;Basit Harmonik Hareketler&lt;br /&gt;&lt;br /&gt;&lt;applet code="shm.class" width=540 height=300 codebase="http://www.phy.ntnu.edu.tw/java/shm/"&gt;&lt;br /&gt;&lt;param name="yellow" value="yellow"&gt;&lt;br /&gt;&lt;param name="blue" value="blue"&gt;&lt;br /&gt;&lt;param name="bgColor" value="lightGray"&gt;&lt;br /&gt;&lt;param name="Reset" value="Reset"&gt;&lt;br /&gt;&lt;param name="Start" value="Start"&gt;&lt;/applet&gt;&lt;br /&gt;&lt;br /&gt;Çıkrıklar&lt;br /&gt;&lt;br /&gt;&lt;applet code="wheel.class" width=500 height=360 codebase="http://www.phy.ntnu.edu.tw/java/wheelAxle/"&gt;&lt;param name="Reset" value="Reset"&gt;&lt;/applet&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-4356767573717820562?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/4356767573717820562/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=4356767573717820562' title='1 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/4356767573717820562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/4356767573717820562'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2009/12/fizik-icin-java-appletleri.html' title='Fizik için Java Applet&apos;leri'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-3682136538474127116</id><published>2009-12-05T09:50:00.000-08:00</published><updated>2009-12-14T07:50:44.787-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java Eğitimi'/><category scheme='http://www.blogger.com/atom/ns#' term='JTPD'/><title type='text'>Eskişehir'de İki Günlük Java Eğitimi</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_9vaXx_lumNA/SyZebxtvZ5I/AAAAAAAAAG8/piayruKDKrQ/s1600-h/eskiehirdeJava1.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 226px; height: 320px;" src="http://3.bp.blogspot.com/_9vaXx_lumNA/SyZebxtvZ5I/AAAAAAAAAG8/piayruKDKrQ/s320/eskiehirdeJava1.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5415119433254266770" /&gt;&lt;/a&gt;&lt;a href="http://www.jtpd.org/"&gt;Java Teknolojileri ve Programcıları Derneği&lt;/a&gt; ile &lt;a href="http://www.esoguieee.com/"&gt;Eskişehir Osmangazi Üniversitesi IEEE Öğrenci Kolu&lt;/a&gt; işbirliğiyle 19 - 20 Aralık 2009 tarihlerinde Java Eğitimi yapılacaktır.&lt;br /&gt;&lt;br /&gt;Kayıt için  : &lt;a href="http://www.esoguieee.com/java/index.asp"&gt;http://www.esoguieee.com&lt;/a&gt;&lt;br /&gt;Facebook Etkinliği : &lt;a href="http://www.facebook.com/event.php?eid=202434030753"&gt;FaceBook&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Program :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Cumartesi Programı&lt;/span&gt;&lt;br /&gt;09:00 - 12:00 Temel Java ve Nesneye Yönelik Programlama&lt;br /&gt;13:00 - 17:00 JSP &amp; Servlet ile Web Uygulaması Geliştirme&lt;br /&gt;              Web Çatıları (Web Frameworks)&lt;br /&gt;              Tasarım Kalıpları&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Pazar Programı&lt;/span&gt;&lt;br /&gt;09:00 - 12:00 Temel Java Laboratuar Çalışması&lt;br /&gt;13:00 - 17:00 Temel Java, JSP &amp; Servlet Laboratuar Çalışması&lt;br /&gt;&lt;br /&gt;Eğitim Veren : Taner Diler (Java Teknolojileri ve Programcıları Başkan Yardımcısı)&lt;br /&gt;&lt;br /&gt;19 Aralık Cumartesi günü yapılacak etkinlik: Eskişehir Osmangazi Üniversitesi Meşeli Kampüsü Prof Dr Necla Özdemir Konferans Salonu&lt;br /&gt;&lt;br /&gt;20 Aralık Pazar günü yapılacak etkinlik: Eskişehir Osmangazi Üniversitesi Meşeli Kampüsü Elektronik Laboratuvar Binası&lt;br /&gt;&lt;br /&gt;Etkinlik hakkında detaylı bilgi almak:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;UTKU BALABAN&lt;/span&gt;     E-Posta : blbanutku@gmail.com          GSM:05062163427&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;DOĞUKAN ERDOĞAN&lt;/span&gt;  E-Posta : hannibal_dodo@hotmail.com    GSM:05063584575&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-3682136538474127116?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/3682136538474127116/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=3682136538474127116' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/3682136538474127116'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/3682136538474127116'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2009/12/eskisehirde-iki-gunluk-java-egitimi.html' title='Eskişehir&apos;de İki Günlük Java Eğitimi'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_9vaXx_lumNA/SyZebxtvZ5I/AAAAAAAAAG8/piayruKDKrQ/s72-c/eskiehirdeJava1.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1447805187508565242.post-228676183290472594</id><published>2009-11-25T04:02:00.000-08:00</published><updated>2010-01-08T04:53:47.543-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wicket'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='JTPD'/><title type='text'>Maven Spring Wicket Hibernate Entegrasyonu</title><content type='html'>İzleyeceğimiz adımlar:&lt;br /&gt;&lt;br /&gt;1. Maven kurulumu&lt;br /&gt;2. Pom.xml'in oluşturulması, Spring Container'i için gerekli paket bağımlılık ayarlarının yapılması&lt;br /&gt;3. Spring application-context.xml'in oluşturulması ve basit bir uygulama ile injection yönetiminin test edilmesi&lt;br /&gt;4. Hibernate paket bağımlılık ayarlarının yapılması ve Hibernate konfigurasyonunun gerçekleştirilmesi&lt;br /&gt;5. Wicket için pom.xml üzerinde paket bağımlılık ayarlarının yapılması&lt;br /&gt;6. Spring application-context.xml ve web.xml de Spring ve Wicket ayarlarının yapılması&lt;br /&gt;&lt;br /&gt;Maven kurulumu için www.maven.org sitesinden maven paketini indirip açtıktan sonra içerisindeki bin klasörününü de sistemin “Ortam Değişkenleri”ne tanımlayabilirsiniz.&lt;br /&gt;&lt;br /&gt;mvn archetype:create -DgroupId=org.jtpd \&lt;br /&gt;                          -DartifactId=maven_spring_hibernate_wicket \&lt;br /&gt;                          -DpackageName=org.jtpd.mshw&lt;br /&gt;&lt;br /&gt;komutunu kullanarak maven projemizi oluşturalım.&lt;br /&gt;&lt;br /&gt;Oluşan pom.xml :&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&lt;project&gt;&lt;br /&gt; &lt;modelversion&gt;4.0.0&lt;/modelversion&gt;&lt;br /&gt; &lt;groupid&gt;org.jtpd&lt;/groupid&gt;&lt;br /&gt; &lt;artifactid&gt;maven_spring_hibernate_wicket&lt;/artifactid&gt;&lt;br /&gt; &lt;packaging&gt;war&lt;/packaging&gt;&lt;br /&gt; &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;&lt;br /&gt; &lt;name&gt;maven_spring_hibernate_wicket&lt;/name&gt;&lt;br /&gt; &lt;url&gt;http://maven.apache.org&lt;/url&gt;&lt;br /&gt; &lt;dependencies&gt;&lt;br /&gt;  &lt;dependency&gt;&lt;br /&gt;   &lt;groupid&gt;junit&lt;/groupid&gt;&lt;br /&gt;   &lt;artifactid&gt;junit&lt;/artifactid&gt;&lt;br /&gt;   &lt;version&gt;3.8.1&lt;/version&gt;&lt;br /&gt;   &lt;scope&gt;test&lt;/scope&gt;&lt;br /&gt;  &lt;/dependency&gt;&lt;br /&gt;  &lt;dependency&gt;&lt;br /&gt;   &lt;groupid&gt;org.slf4j&lt;/groupid&gt;&lt;br /&gt;   &lt;artifactid&gt;slf4j-jdk14&lt;/artifactid&gt;&lt;br /&gt;   &lt;version&gt;1.4.2&lt;/version&gt;&lt;br /&gt;  &lt;/dependency&gt;&lt;br /&gt;&lt;/dependencies&gt;&lt;br /&gt;&lt;/project&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Oluşan dizin yapısı:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;maven_spring_hibernate_wicket/&lt;br /&gt;maven_spring_hibernate_wicket/pom.xml&lt;br /&gt;     /src/&lt;br /&gt;     /src/main/&lt;br /&gt;         /main/java&lt;br /&gt;     /src/test/&lt;br /&gt;         /test/java&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Log4j, Spring gibi konfigurasyon dosyalarını koymak için /src/main/resources dizinini ve web dosyalarını koymak için /src/main/webapp oluşturalım. Ve sonrasında pom.xml'i açıp aşağıdaki ayarlamaları yapalım.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt; &lt;build&gt;&lt;br /&gt;   &lt;resources&gt;&lt;br /&gt;     &lt;resource&gt;&lt;br /&gt;       &lt;directory&gt;src/main/resources&lt;/directory&gt;&lt;br /&gt;       &lt;filtering&gt;true&lt;/filtering&gt;&lt;br /&gt;     &lt;/resource&gt;&lt;br /&gt;   &lt;/resources&gt;&lt;br /&gt;  &lt;plugins&gt;&lt;br /&gt;  &lt;plugin&gt;&lt;br /&gt;    &lt;groupid&gt;org.apache.maven.plugins&lt;/groupid&gt;&lt;br /&gt;    &lt;artifactid&gt;maven-compiler-plugin&lt;/artifactid&gt;&lt;br /&gt;    &lt;version&gt;2.0.2&lt;/version&gt;&lt;br /&gt;    &lt;configuration&gt;&lt;br /&gt;   &lt;source&gt;1.5&lt;br /&gt;   &lt;target&gt;1.5&lt;/target&gt;&lt;br /&gt;    &lt;/configuration&gt;&lt;br /&gt;  &lt;/plugin&gt;&lt;br /&gt;  &lt;/plugins&gt;&lt;br /&gt;&lt;/build&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Gelin şimdi Spring &amp;amp; Hibernate paket bağımlılıklarını ayarlayalım:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&lt;dependencies&gt;&lt;br /&gt;...&lt;br /&gt;     &lt;!--  SPRING DEPENDENCIES  --&gt;&lt;br /&gt; &lt;dependency&gt;&lt;br /&gt;         &lt;groupid&gt;org.springframework&lt;/groupid&gt;&lt;br /&gt;         &lt;artifactid&gt;spring&lt;/artifactid&gt;&lt;br /&gt;         &lt;version&gt;${spring.version}&lt;/version&gt;&lt;br /&gt;     &lt;/dependency&gt;&lt;br /&gt; &lt;dependency&gt;&lt;br /&gt;         &lt;groupid&gt;org.springframework&lt;/groupid&gt;&lt;br /&gt;         &lt;artifactid&gt;spring-web&lt;/artifactid&gt;&lt;br /&gt;         &lt;version&gt;${spring.version}&lt;/version&gt;&lt;br /&gt;     &lt;/dependency&gt;&lt;br /&gt; &lt;dependency&gt;&lt;br /&gt;  &lt;groupid&gt;org.springframework&lt;/groupid&gt;&lt;br /&gt;  &lt;artifactid&gt;spring-aspects&lt;/artifactid&gt;&lt;br /&gt;  &lt;version&gt;${spring.version}&lt;/version&gt;&lt;br /&gt; &lt;/dependency&gt;&lt;br /&gt;     &lt;!--  HIBERNATE DEPENDENCIES  --&gt;&lt;br /&gt; &lt;dependency&gt;&lt;br /&gt;  &lt;groupid&gt;mysql&lt;/groupid&gt;&lt;br /&gt;  &lt;artifactid&gt;mysql-connector-java&lt;/artifactid&gt;&lt;br /&gt;  &lt;version&gt;5.1.6&lt;/version&gt;&lt;br /&gt; &lt;/dependency&gt;&lt;br /&gt;     &lt;dependency&gt;&lt;br /&gt;  &lt;groupid&gt;javax.persistence&lt;/groupid&gt;&lt;br /&gt;  &lt;artifactid&gt;persistence-api&lt;/artifactid&gt;&lt;br /&gt;  &lt;version&gt;1.0&lt;/version&gt;&lt;br /&gt;  &lt;scope&gt;provided&lt;/scope&gt;&lt;br /&gt; &lt;/dependency&gt;&lt;br /&gt; &lt;dependency&gt;&lt;br /&gt;  &lt;groupid&gt;org.hibernate&lt;/groupid&gt;&lt;br /&gt;  &lt;artifactid&gt;hibernate-annotations&lt;/artifactid&gt;&lt;br /&gt;  &lt;version&gt;3.4.0.GA&lt;/version&gt;&lt;br /&gt; &lt;/dependency&gt;&lt;br /&gt; &lt;dependency&gt;&lt;br /&gt;  &lt;groupid&gt;org.hibernate&lt;/groupid&gt;&lt;br /&gt;  &lt;artifactid&gt;hibernate-entitymanager&lt;/artifactid&gt;&lt;br /&gt;  &lt;version&gt;3.4.0.GA&lt;/version&gt;&lt;br /&gt; &lt;/dependency&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/dependencies&gt;&lt;br /&gt;&lt;br /&gt;&lt;properties&gt;&lt;br /&gt;&lt;spring.version&gt;2.5.6&lt;/spring.version&gt;&lt;br /&gt;&lt;/properties&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Spring konfigurasyonunu gerçekleştirelim. Bunun için src/main/resources altında application-context.xml dosyasını oluşturalım.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&lt;br /&gt;&lt;beans xmlns="http://www.springframework.org/schema/beans" xsi="http://www.w3.org/2001/XMLSchema-instance" util="http://www.springframework.org/schema/util" context="http://www.springframework.org/schema/context" aop="http://www.springframework.org/schema/aop" tx="http://www.springframework.org/schema/tx" p="http://www.springframework.org/schema/p" schemalocation="        http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-2.0.xsd        http://www.springframework.org/schema/util         http://www.springframework.org/schema/util/spring-util-2.0.xsd        http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context-2.1.xsd        http://www.springframework.org/schema/tx        http://www.springframework.org/schema/tx/spring-tx.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;   &lt;context:annotation-config&gt;&lt;br /&gt;   &lt;context:component-scan package="org.jtpd"&gt;&lt;br /&gt;   &lt;aop:aspectj-autoproxy&gt;&lt;br /&gt;   &lt;tx:annotation-driven&gt;&lt;br /&gt;&lt;br /&gt;   &lt;bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"&gt;&lt;br /&gt;       &lt;property name="dataSource" ref="dataSource"&gt;&lt;br /&gt;      &lt;br /&gt;       &lt;property name="annotatedClasses"&gt;&lt;br /&gt;           &lt;list&gt;&lt;br /&gt;               &lt;value&gt;org.jtpd.core.User&lt;/value&gt;&lt;br /&gt;   &lt;value&gt;...&lt;/value&gt;&lt;br /&gt;           &lt;/list&gt;&lt;br /&gt;       &lt;/property&gt;&lt;br /&gt;&lt;br /&gt;       &lt;property name="hibernateProperties"&gt;&lt;br /&gt;           &lt;props&gt;&lt;br /&gt;               &lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.MySQLDialect&lt;/prop&gt;&lt;br /&gt;               &lt;prop key="hibernate.show_sql"&gt;true&lt;/prop&gt;&lt;br /&gt;           &lt;/props&gt;&lt;br /&gt;       &lt;/property&gt;&lt;br /&gt;   &lt;/property&gt;&lt;br /&gt;&lt;br /&gt;   &lt;bean id="dataSource" class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource" method="close"&gt;&lt;br /&gt;       &lt;property name="url" value="jdbc:mysql://db.jtpd.org:3306/jtpd"&gt;&lt;br /&gt;       &lt;property name="user" value="root"&gt;&lt;br /&gt;       &lt;property name="password" value="****"&gt;&lt;br /&gt;   &lt;/property&gt;&lt;br /&gt;&lt;br /&gt;   &lt;bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt;&lt;br /&gt;       &lt;property name="sessionFactory" ref="sessionFactory"&gt;&lt;br /&gt;       &lt;property name="dataSource" ref="dataSource"&gt;&lt;br /&gt;   &lt;/property&gt;&lt;br /&gt;&lt;/property&gt;&lt;br /&gt;&lt;br /&gt;&lt;/bean&gt;&lt;/property&gt;&lt;/property&gt;&lt;/bean&gt;&lt;/bean&gt;&lt;/tx:annotation-driven&gt;&lt;/aop:aspectj-autoproxy&gt;&lt;/context:component-scan&gt;&lt;/context:annotation-config&gt;&lt;/beans&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Yukarıdaki konfigurasyonda, spring injectionlarının ve transaction tanımlarının annotationlar üzerinden yapılacağı belirtilir.&lt;br /&gt;&lt;br /&gt;Uygulama içerisindeki kullanımı&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@Entity&lt;br /&gt;@Table(name=”User”)&lt;br /&gt;public class User {&lt;br /&gt;   @Id&lt;br /&gt; @GeneratedValue(strategy=GenerationType.IDENTITY)&lt;br /&gt; private Integer id;&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Repository  //Spring Annotation&lt;br /&gt;@Transactional&lt;br /&gt;public abstract GenericDAO&lt;t&gt; {&lt;br /&gt; &lt;br /&gt;  @Autowired   //Spring Annotation&lt;br /&gt;  private SessionFactory sessionFactory;&lt;br /&gt;&lt;br /&gt;  public Session getSession(){&lt;br /&gt;      return sessionFactory.openSession();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void save(T entity){&lt;br /&gt;      getSession().save(entity);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Repository  //Spring Annotation&lt;br /&gt;@Transactional&lt;br /&gt;public class UserDAO extends GenericDAO&lt;user&gt; {&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Service  //Spring Annotation&lt;br /&gt;@Transactional&lt;br /&gt;public UserService {&lt;br /&gt;&lt;br /&gt;  @Autowired   //Spring Annotation&lt;br /&gt;  private IuserDAO userDAO;&lt;br /&gt;&lt;br /&gt;  //Ornek&lt;br /&gt;  public void save(User user){&lt;br /&gt;      // Transaction Yönetimi spring tarafindan yapilmakta&lt;br /&gt;      userDAO.save(user); &lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/user&gt;&lt;/t&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Şu ana kadar yazmış olduğumuz kod örneğini ve konfigurasyonu test etmek için standalone çalışabilecek bir kod çalışması yapalım. Öncelikle pom.xml içerisinde aşağıdaki konfigurasyonu yapalım.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt; &lt;build&gt;&lt;br /&gt;        &lt;plugins&gt;&lt;br /&gt;        ...  &lt;br /&gt;                &lt;plugin&gt;&lt;br /&gt;    &lt;groupid&gt;org.codehaus.mojo&lt;/groupid&gt;&lt;br /&gt;    &lt;artifactid&gt;exec-maven-plugin&lt;/artifactid&gt;&lt;br /&gt;    &lt;executions&gt;&lt;br /&gt;     &lt;execution&gt;&lt;br /&gt;      &lt;phase&gt;package&lt;/phase&gt;&lt;br /&gt;      &lt;goals&gt;&lt;br /&gt;       &lt;goal&gt;java&lt;/goal&gt;&lt;br /&gt;      &lt;/goals&gt;&lt;br /&gt;     &lt;/execution&gt;&lt;br /&gt;    &lt;/executions&gt;&lt;br /&gt;&lt;br /&gt;    &lt;configuration&gt;&lt;br /&gt;     &lt;mainclass&gt;org.jtpd.App&lt;/mainclass&gt;&lt;br /&gt;    &lt;/configuration&gt;&lt;br /&gt;   &lt;/plugin&gt;&lt;br /&gt;         ...&lt;br /&gt;         &lt;/plugins&gt;&lt;br /&gt;      &lt;/build&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;org.jtpd.App java dosyasını oluşturalım:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;package org.jtpd;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;import org.springframework.context.ApplicationContext;&lt;br /&gt;import org.springframework.context.support.FileSystemXmlApplicationContext;&lt;br /&gt;&lt;br /&gt;public class App {&lt;br /&gt;&lt;br /&gt; public static void main(String[] args) {&lt;br /&gt;  try {&lt;br /&gt;   ApplicationContext factory = new FileSystemXmlApplicationContext(&lt;br /&gt;     "target\\classes\\application-context.xml");&lt;br /&gt;   IUserService userService = (IUserService) factory&lt;br /&gt;     .getBean("userService");&lt;br /&gt;                 userService.save(new User());&lt;br /&gt;  } catch (Exception e) {&lt;br /&gt;   e.printStackTrace();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;App sınıfını komut satırından&lt;br /&gt;&lt;br /&gt;mvn exec:java&lt;br /&gt;&lt;br /&gt;komutu ile çalıştırabiliriz.&lt;br /&gt;&lt;br /&gt;Herşey istediğimiz gibi ise şimdi geliştirdiğimiz yapıyı web uygulaması haline getirelim. Bunun için pom.xml'de :&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;      &lt;dependencies&gt;&lt;br /&gt;           ...&lt;br /&gt;  &lt;dependency&gt;&lt;br /&gt;   &lt;groupid&gt;org.apache.wicket&lt;/groupid&gt;&lt;br /&gt;   &lt;artifactid&gt;wicket-spring&lt;/artifactid&gt;&lt;br /&gt;   &lt;version&gt;${wicket.version}&lt;/version&gt;&lt;br /&gt;  &lt;/dependency&gt;  &lt;br /&gt;  &lt;dependency&gt;&lt;br /&gt;   &lt;groupid&gt;org.apache.wicket&lt;/groupid&gt;&lt;br /&gt;   &lt;artifactid&gt;wicket&lt;/artifactid&gt;&lt;br /&gt;   &lt;version&gt;${wicket.version}&lt;/version&gt;&lt;br /&gt;  &lt;/dependency&gt;&lt;br /&gt;  &lt;dependency&gt;&lt;br /&gt;   &lt;groupid&gt;org.apache.wicket&lt;/groupid&gt;&lt;br /&gt;   &lt;artifactid&gt;wicket-extensions&lt;/artifactid&gt;&lt;br /&gt;   &lt;version&gt;${wicket.version}&lt;/version&gt;&lt;br /&gt;  &lt;/dependency&gt;&lt;br /&gt;           &lt;/dependencies&gt;&lt;br /&gt;  &lt;br /&gt;      ...&lt;br /&gt;&lt;br /&gt;  &lt;properties&gt;&lt;br /&gt;  &lt;wicket.version&gt;1.4.0&lt;/wicket.version&gt;&lt;br /&gt;  &lt;spring.version&gt;2.5.6&lt;/spring.version&gt;&lt;br /&gt;  &lt;/properties&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;src/main/webapp altında WEB-INF/web.xml dosyasını oluşturalım ve aşağıdaki konfigurasyonları tanımlayalım&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&lt;br /&gt;&lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee" xsi="http://www.w3.org/2001/XMLSchema-instance" schemalocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"&gt;&lt;br /&gt;&lt;br /&gt;   &lt;display-name&gt;JTPD&lt;/display-name&gt;&lt;br /&gt;&lt;br /&gt;   &lt;filter&gt;&lt;br /&gt;       &lt;filter-name&gt;wicket-spring-hibernate&lt;/filter-name&gt;&lt;br /&gt;       &lt;filter-class&gt;org.apache.wicket.protocol.http.WicketFilter&lt;/filter-class&gt;&lt;br /&gt;       &lt;init-param&gt;&lt;br /&gt;           &lt;param-name&gt;applicationFactoryClassName&lt;/param-name&gt;&lt;br /&gt;           &lt;param-value&gt;org.apache.wicket.spring.SpringWebApplicationFactory&lt;/param-value&gt;&lt;br /&gt;       &lt;/init-param&gt;&lt;br /&gt;   &lt;/filter&gt;&lt;br /&gt;&lt;br /&gt;   &lt;filter-mapping&gt;&lt;br /&gt;       &lt;filter-name&gt;wicket-spring-hibernate&lt;/filter-name&gt;&lt;br /&gt;       &lt;url-pattern&gt;/*&lt;/url-pattern&gt;&lt;br /&gt;   &lt;/filter-mapping&gt;&lt;br /&gt;  &lt;br /&gt;   &lt;context-param&gt;&lt;br /&gt;  &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;&lt;br /&gt;  &lt;param-value&gt;classpath:application-context.xml&lt;/param-value&gt;&lt;br /&gt; &lt;/context-param&gt;&lt;br /&gt; &lt;br /&gt; &lt;listener&gt;&lt;br /&gt;  &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;&lt;br /&gt; &lt;/listener&gt;&lt;br /&gt;&lt;br /&gt;&lt;/web-app&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Web.xml de  Spring ve Wicket çatılarına ait tanımlamaları yaptık.application-context.xml içerisinde de Wicket uygulamasını tanımlamamız gerekiyor. Web.xml içerisinde  WicketFilter konfigurasyonunda Wicket çatısına aşağıdaki WebApplication sınıfını hangi factory üzerinden alacağımızı belirtiyoruz. Burada Wicket ile Spring entegrasyonunu gerçekleştirmiş oluyoruz.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;...&lt;br /&gt;&lt;bean id="wicketApplication" class="org.jtpd.web.JTPDWicketApplication"&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/bean&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Şu ana kadar Maven, Spring, Hibernate ve Wicket entegrasyonunu bir şekilde gerçekleştirmiş bulunmaktayız. Fakat Wicket bileşenlerinden Spring bean'lerine injection yöntemiyle erişmek için JTPDWicketApplication sınıfının yapılandırıcı yordamlarında&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;addComponentInstantiationListener(new SpringComponentInjector(this));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;çağırımlarını yapmamız gerekmektedir.&lt;br /&gt;&lt;br /&gt;JTPDWicketApplication sınıfı :&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package org.jtpd.web.JTPDWicketApplication;&lt;br /&gt;&lt;br /&gt;import org.apache.wicket.protocol.http.WebApplication;&lt;br /&gt;import org.apache.wicket.spring.injection.annot.SpringComponentInjector;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Application object for your web application.&lt;br /&gt;* &lt;p&gt;&lt;br /&gt;* If you want to run this application without deploying, run the Start class.&lt;br /&gt;*/&lt;br /&gt;public class JTPDWicketApplication extends WebApplication {&lt;br /&gt;&lt;br /&gt; /* (non-Javadoc)&lt;br /&gt;  * @see org.apache.wicket.protocol.http.WebApplication#init()&lt;br /&gt;  */&lt;br /&gt; @Override&lt;br /&gt; protected void init() {&lt;br /&gt;  // TODO Auto-generated method stub&lt;br /&gt;  super.init();&lt;br /&gt;  addComponentInstantiationListener(new SpringComponentInjector(this));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public Class&lt;Index&gt; getHomePage() {&lt;br /&gt;  return Index.class;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;WebApplication, WebPage gibi Wicket bileşenleri içerisinden Spring bean'lerini kullanabilmek için @SpringBean annotation'ını kullanmamız gerekmektedir. JTPDWebApplication içerisinden çağırılan Index.class yani WebPage'den türeyen Index sınıfını oluşturalım ve buradan userService Spring Bean'ini nasıl çağırdığımızı görelim.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package org.jtpd.web;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* @author tdiler&lt;br /&gt;*&lt;br /&gt;*/&lt;br /&gt;import org.apache.wicket.PageParameters;&lt;br /&gt;import org.apache.wicket.markup.html.WebPage;&lt;br /&gt;import org.apache.wicket.markup.html.basic.Label;&lt;br /&gt;import org.apache.wicket.spring.injection.annot.SpringBean;&lt;br /&gt;import org.jtpd.core.IUserService;&lt;br /&gt;import org.jtpd.core.User;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Homepage&lt;br /&gt;*/&lt;br /&gt;public class Index extends WebPage {&lt;br /&gt;&lt;br /&gt; private static final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt; @SpringBean&lt;br /&gt; IUserService userService;&lt;br /&gt;&lt;br /&gt; public Index(final PageParameters parameters) {&lt;br /&gt;  User user = new User();&lt;br /&gt;  userService.save(user);&lt;br /&gt;  add(new Label("label", "Kullanıcı kaydedildi."));&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Wicket çatısında yazılan WebPage, Panel gibi bileşenler için markup tanımlarını içeren  sınıf ile aynı isimde *.html uzantılı dosyalar bulunmalıdır. Maven ile derleme ve paket oluşturma sonucunda bu html dosyalarınında değerlendirilmesi için pom.xml’de şu eklemeyi yapacağız:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&lt;resources&gt;&lt;br /&gt;...&lt;br /&gt; &lt;resource&gt;&lt;br /&gt;  &lt;filtering&gt;false&lt;/filtering&gt;&lt;br /&gt;  &lt;directory&gt;src/main/java&lt;/directory&gt;&lt;br /&gt;  &lt;includes&gt;&lt;br /&gt;   &lt;include&gt;**&lt;/include&gt;&lt;br /&gt;  &lt;/includes&gt;&lt;br /&gt;  &lt;excludes&gt;&lt;br /&gt;   &lt;exclude&gt;**/*.java&lt;/exclude&gt;&lt;br /&gt;  &lt;/excludes&gt;&lt;br /&gt; &lt;/resource&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/resources&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;İlgili çalışmaya ait kodlara &lt;a href="http://rapidshare.com/files/283790982/maven_spring_hibernate_wicket.rar.html"&gt;buradan&lt;/a&gt; ulaşabilirsiniz.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1447805187508565242-228676183290472594?l=tanerdiler.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tanerdiler.blogspot.com/feeds/228676183290472594/comments/default' title='Kayıt Yorumları'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1447805187508565242&amp;postID=228676183290472594' title='0 Yorum'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/228676183290472594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1447805187508565242/posts/default/228676183290472594'/><link rel='alternate' type='text/html' href='http://tanerdiler.blogspot.com/2009/11/maven-spring-wicket-hibernate.html' title='Maven Spring Wicket Hibernate Entegrasyonu'/><author><name>&lt;a href="http://tr.linkedin.com/pub/taner-diler/5/94b/6a0"&gt;Taner Diler&lt;/a&gt;</name><uri>http://www.blogger.com/profile/05667700075217873328</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
