<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Try it. And catch it, finally.</title>
	
	<link>http://developing.schimak.at</link>
	<description>Developing software means to be careful and fast, critical and compliant, visionary and pragmatic. Concurrently. It means to listen thoroughly - and to decide yourself...</description>
	<lastBuildDate>Tue, 08 Dec 2009 23:34:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.3</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/TryItAndCatchItFinally" /><feedburner:info uri="tryitandcatchitfinally" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/2.0/</creativeCommons:license><item>
		<title>Bitemporal Data is everywhere – Part 1</title>
		<link>http://feedproxy.google.com/~r/TryItAndCatchItFinally/~3/eblzJCXbJNE/</link>
		<comments>http://developing.schimak.at/2009/12/bitemporal-data-is-everywhere-part-1/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 21:37:16 +0000</pubDate>
		<dc:creator>Martin Schimak</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Bitemporality]]></category>
		<category><![CDATA[Lifecycle]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[Temporal]]></category>
		<category><![CDATA[Versioning]]></category>

		<guid isPermaLink="false">http://developing.schimak.at/?p=271</guid>
		<description><![CDATA[
In this writing:
- Record Time
- Actual Time
- Bitemporality

While still in the middle of taking care of my momentarily sick little girls, I will today continue the reflections about the lifecycle of data and go through a sample of temporal data to further illustrate what I am speaking about. Bitemporality: this e.g. is how Martin Fowler [...]]]></description>
			<content:encoded><![CDATA[
<div style="float: right; margin-right: 10px; margin-left: 10px; margin-top: 3px; margin-bottom: 3px; border: 1px solid lightgrey; padding: 7px"><em>In this writing</em>:<br />
- <a href="#record-temporal"><strong>Record Time</strong></a><br />
- <a href="#actual-temporal"><strong>Actual Time</strong></a><br />
- <a href="#bi-temporal"><strong>Bitemporality</strong></a>
</div>
<p>While still in the middle of taking care of my momentarily sick little girls, I will today continue the reflections <a href="http://developing.schimak.at/2009/11/about-the-lifecycle-of-data/">about the lifecycle of data</a> and go through a sample of <strong>temporal</strong> data to further illustrate what I am speaking about. Bitemporality: this e.g. is how Martin Fowler (<a href="http://martinfowler.com/ap2/timeNarrative.html">Patterns for things that change with time</a>) describes the two time dimensions of <strong>Bitemporal</strong> Objects:</p>
<blockquote><p>I think of the first dimension as <strong>actual time</strong>: the time something happened. The second dimension is <strong>record time</strong>, the time we knew about it. Whenever something happens, there are always these two times that come with it.</p></blockquote>
<p><img src="http://farm3.static.flickr.com/2459/3700985051_4b7a179e88.jpg"></img><br />
<span style="font-size: 9px">Foto credits to <a href="http://www.flickr.com/photos/bobydimitrov/3700985051/">bobydimitrov</a> according Creative Commons <a href="http://creativecommons.org/licenses/by-sa/2.0/deed.en">BY-SA 2.0</a></span></p>
<p><em>&#8220;Whenever something happens, there are always these two times that come with it.&#8221;</em>: the information that something happened itself needs time until it reaches its recipients and maybe even more time until it is recorded in some database&#8230; and this of course does not just concern a lightning and the subsequent reception of the thunder within some miles, it does not just concern the recording of the lightnings in some weather forecasters database or the reader of a local newspaper covering this thunderstorm. It concerns every single profane fact of life.</p>
<h2><a name="record-temporal">Tracking Record Time</a></h2>
<p>Let&#8217;s therefore focus on such a profane fact of life and investigate the relationship between a hotel room and it&#8217;s price. Let&#8217;s imagine a simplified Price Watcher Application tracking the Prices of the rooms of several hotels in a given city:</p>

<table id="wp-table-reloaded-id-1-no-1" class="wp-table-reloaded wp-table-reloaded-id-1">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Hotel</th><th class="column-2">Room</th><th class="column-3">Price</th>
	</tr>
</thead>
<tbody>
	<tr class="row-2 even">
		<td class="column-1">"Four Seasons"</td><td class="column-2">Single Standard</td><td class="column-3">€ 149.00</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">"Bedtime" Lodge</td><td class="column-2">Single Standard</td><td class="column-3">€ 98.00</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">"In good hands"</td><td class="column-2">Single Standard</td><td class="column-3">€ 110.00</td>
	</tr>
</tbody>
</table>

<p>A better normalised real life database schema for such an application would of course look a bit different, but this should not bother us at the moment: with this simple table we can already answer the question <em>&#8220;Where do I get the cheapest city hotel room at the moment?&#8221;</em> sorting the table by price in descending order&#8230; but actually&#8230; can we answer this? To be slightly more precise &#8211; and we have to be precise for our topic &#8211; we can just answer the question <em>&#8220;Where do we get <strong>to our current knowledge</strong> the cheapest city hotel room at the moment?&#8221;</em>. After all, we don&#8217;t reflect reality here, we just reflect what we know about it&#8230;</p>
<p>If our Price Watcher App eventually becomes a relevant factor in the market, conflicts with hotel owners could occur more frequently (&#8221;Why do you update just my price cuttings so slowly?&#8221;). We therefore might want to add the information when exactly the specific price was recorded with us:</p>

<table id="wp-table-reloaded-id-2-no-1" class="wp-table-reloaded wp-table-reloaded-id-2">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Hotel</th><th class="column-2">Room</th><th class="column-3">Price</th><th class="column-4">Recorded at</th>
	</tr>
</thead>
<tbody>
	<tr class="row-2 even">
		<td class="column-1">"Four Seasons"</td><td class="column-2">Single Standard</td><td class="column-3">€ 149.00</td><td class="column-4">12/01/2009 18:03</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">"Bedtime" Lodge</td><td class="column-2">Single Standard</td><td class="column-3">€ 98.00</td><td class="column-4">11/28/2009 11:54</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">"In good hands"</td><td class="column-2">Single Standard</td><td class="column-3">€ 110.00</td><td class="column-4">12/07/2009 08:11</td>
	</tr>
</tbody>
</table>

<p>But thinking about this twice, wouldn&#8217;t it be wise not just to remember when we updated the price the last time, but to remember many such updates in order to be able to discuss single cases and to proove that we honestly treat all hotels equally? Well, then we may <strong>not update</strong> the table anymore but instead <strong>insert</strong> a new row whenever a price change occurs. Let&#8217;s for this purpose focus on &#8220;Bedtime Lodge&#8221; from here on:</p>

<table id="wp-table-reloaded-id-3-no-1" class="wp-table-reloaded wp-table-reloaded-id-3">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Hotel</th><th class="column-2">Room</th><th class="column-3">Price</th><th class="column-4">Recorded at</th>
	</tr>
</thead>
<tbody>
	<tr class="row-2 even">
		<td class="column-1">"Bedtime" Lodge</td><td class="column-2">Single Standard</td><td class="column-3">€ 101.00</td><td class="column-4">10/31/2009 10:17</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">"Bedtime" Lodge</td><td class="column-2">Single Standard</td><td class="column-3">€ 98.00</td><td class="column-4">11/28/2009 11:54</td>
	</tr>
</tbody>
</table>

<p>Now, let&#8217;s back-pedal at this point a little bit by &#8220;denormalising&#8221; the information we already have here: we add another column, which serves to reflect until which point in time we considered the associated information to be valid: it is the moment when the price for one hotel changed and we therefore added a new row: </p>

<table id="wp-table-reloaded-id-4-no-1" class="wp-table-reloaded wp-table-reloaded-id-4">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Hotel</th><th class="column-2">Room</th><th class="column-3">Price</th><th class="column-4">Recorded at</th><th class="column-5">Effective until</th>
	</tr>
</thead>
<tbody>
	<tr class="row-2 even">
		<td class="column-1">"Bedtime" Lodge</td><td class="column-2">Single Standard</td><td class="column-3">€ 101.00</td><td class="column-4">10/31/2009 10:17</td><td class="column-5">11/28/2009 11:54</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">"Bedtime" Lodge</td><td class="column-2">Single Standard</td><td class="column-3">€ 98.00</td><td class="column-4">11/28/2009 11:54</td><td class="column-5">unlimited</td>
	</tr>
</tbody>
</table>

<p>We realize: the new &#8220;Effective until&#8221; information is &#8220;unlimited&#8221; for new rows. And it is equal to the &#8220;Recorded At&#8221; Column of the new Row, the moment we &#8220;update&#8221; it by inserting a new row. Now: whenever we ask for <strong>current prices</strong>, we will want to filter out all the rows with outdated effectivity. But actually we should generalize this filtering procedure a bit: <strong>whenever</strong> we ask this table for a consistent set of data given at the current <strong>or</strong> a historic date, we always filter out rows for which this date is not in between &#8220;Recorded at&#8221; and &#8220;Effective until&#8221;. In order to make this even easier, we could decide to replace the &#8220;unlimited&#8221; with a date far enough in the future in order not to cause any Y2K problematic during our lifetime:</p>

<table id="wp-table-reloaded-id-7-no-1" class="wp-table-reloaded wp-table-reloaded-id-7">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Hotel</th><th class="column-2">Room</th><th class="column-3">Price</th><th class="column-4">Recorded at</th><th class="column-5">Effective until</th>
	</tr>
</thead>
<tbody>
	<tr class="row-2 even">
		<td class="column-1">"Bedtime" Lodge</td><td class="column-2">Single Standard</td><td class="column-3">€ 101.00</td><td class="column-4">10/31/2009 10:17</td><td class="column-5">11/28/2009 11:54</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">"Bedtime" Lodge</td><td class="column-2">Single Standard</td><td class="column-3">€ 98.00</td><td class="column-4">11/28/2009 11:54</td><td class="column-5">31/12/9999 23:59</td>
	</tr>
</tbody>
</table>

<p>And by the way, watching this: wouldn&#8217;t it be nice to show to our users not just the current price, but also things like e.g. how the minimum room price for a given hotel developed in the past or which hotels frequently offer rooms for minimum prices? All the information we need for this already is in place! We would just have to think about the queries a little bit. <img src='http://developing.schimak.at/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<h2><a name="actual-temporal">Tracking Actual Time</a></h2>
<p>Now, question: what&#8217;s <strong>bi</strong>temporal about this data. Answer: so far, nothing. So far, we just cared about <strong>Record Time</strong>, meaning we just cared about the moment we learned about a price change, we did not care so much about when it actually happened. If we call this type of storing data &#8220;Record Temporal&#8221;, we can imagine that we can use a very similar mechanism to store &#8220;Actual Temporal&#8221; Data by changing the semantics of our two Time Columns and call them now <strong>Actual From</strong> and <strong>Actual Until</strong>:</p>

<table id="wp-table-reloaded-id-8-no-1" class="wp-table-reloaded wp-table-reloaded-id-8">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Hotel</th><th class="column-2">Room</th><th class="column-3">Price</th><th class="column-4">Actual from</th><th class="column-5">Actual until</th>
	</tr>
</thead>
<tbody>
	<tr class="row-2 even">
		<td class="column-1">"Bedtime" Lodge</td><td class="column-2">Single Standard</td><td class="column-3">€ 101.00</td><td class="column-4">10/31/2009 10:17</td><td class="column-5">11/28/2009 11:54</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">"Bedtime" Lodge</td><td class="column-2">Single Standard</td><td class="column-3">€ 98.00</td><td class="column-4">11/28/2009 11:54</td><td class="column-5">31/12/9999 23:59</td>
	</tr>
</tbody>
</table>

<p>What changes when giving the columns the semantics of Actual Time compared to Record Time? Well, when it comes to Record Time, it&#8217;s always an easily retrievable <strong>System Time</strong> we deal with: the moment some data is inserted/updated, we change the &#8220;Effective until&#8221; of the old row and the &#8220;Recorded at&#8221; of the new row to the current System Time and are finished. When it comes to Actual Time, things are different. Typically this point in time can just be provided by the human (or external system) using the database application. He/she/it is the only one who can tell: wait, now we update the information in your database, right, but <strong>actually</strong> the change in the real world already happened earlier. Which is why we have to ask ourselves, whether this kind of semantics would add value to our Price Watcher App? Probably not. But: the moment we change perspective on the given sample we find that somebody else will be interested in both Times: the &#8220;Bedtime Lodge&#8221;.</p>
<h2><a name="bi-temporal">Bitemporality</a></h2>
<p>The &#8220;Bedtime Lodge&#8221; will also have to maintain a room and price database with similar contents but just for their own rooms. The goal is now not to &#8220;watch&#8221; prices, but actually to &#8220;define&#8221; and &#8220;maintain&#8221; them. Of course, we don&#8217;t need the &#8220;Hotel&#8221; column anymore, because we definitely know, it&#8217;s us:</p>

<table id="wp-table-reloaded-id-9-no-1" class="wp-table-reloaded wp-table-reloaded-id-9">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Room</th><th class="column-2">Price</th><th class="column-3">Recorded at</th><th class="column-4">Effective until</th>
	</tr>
</thead>
<tbody>
	<tr class="row-2 even">
		<td class="column-1">Single Standard</td><td class="column-2">€ 101.00</td><td class="column-3">10/31/2009 10:17</td><td class="column-4">11/28/2009 11:54</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">Single Standard</td><td class="column-2">€ 98.00</td><td class="column-3">11/28/2009 11:54</td><td class="column-4">31/12/9999 23:59</td>
	</tr>
</tbody>
</table>

<p>The requirement we face here is to be able to define and maintain Prices which come into effect somewhen in the <strong>future</strong>. My next post will therefore combine the Concepts of Record Time and Actual Time and complete the sample showing the full <strong>Bitemporality</strong>.</p>

<img src="http://feeds.feedburner.com/~r/TryItAndCatchItFinally/~4/eblzJCXbJNE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://developing.schimak.at/2009/12/bitemporal-data-is-everywhere-part-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://developing.schimak.at/2009/12/bitemporal-data-is-everywhere-part-1/</feedburner:origLink></item>
		<item>
		<title>About the Lifecycle of Data.</title>
		<link>http://feedproxy.google.com/~r/TryItAndCatchItFinally/~3/alZAN3R-sqE/</link>
		<comments>http://developing.schimak.at/2009/11/about-the-lifecycle-of-data/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 12:50:48 +0000</pubDate>
		<dc:creator>Martin Schimak</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Lifecycle]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[Temporal]]></category>
		<category><![CDATA[Versioning]]></category>

		<guid isPermaLink="false">http://developing.schimak.at/?p=225</guid>
		<description><![CDATA[
Some time ago I wrote a requirements oriented post about controlling the lifecycle of persisted entities. 
Today I want to step back a bit and start writing about a number of &#8220;temporal&#8221; issues and problems of business applications development. On my way of thinking about this stuff I want to discuss, develop and improve (one [...]]]></description>
			<content:encoded><![CDATA[
<p>Some time ago I wrote a requirements oriented post about <a href="http://developing.schimak.at/2009/08/control-over-lifecycle-of-persisted-entities/">controlling the lifecycle of persisted entities</a>. </p>
<p>Today I want to step back a bit and <strong>start</strong> writing about a number of &#8220;temporal&#8221; issues and problems of business applications development. On my way of thinking about this stuff I want to discuss, develop and improve (one or more?) possible solutions for them. This rankles me since a longer time: it&#8217;s the kind of stuff that <em>regularly</em> nobody has <strong>time</strong> (sic!) to care about when a business application project starts and which (again: <em>regularly</em>) begins to hurt and cost (maybe lots of) time and money later on when the true business requirements are discovered. And <em>regularly</em> they are discovered piece by piece only.</p>
<p><img src="http://farm1.static.flickr.com/52/112342184_99652d174d.jpg"></img><br />
<span style="font-size: 9px">Foto credits to <a href="http://www.flickr.com/photos/monkeyc/112342184/">monkeyc.net</a> according Creative Commons <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/deed.en">BY-NC-SA 2.0</a></span></p>
<p>So, what do I mean with <strong>Lifecycle of Data</strong>? At some point in time our baby-data is born. Then, while growing-up and aging it keeps some properties while others will change with time. Until at some point later it will die and disappear from this world. When we compare this picture of life with the basic data manipulation mechanisms a typical database management system provides we find a similar pattern: at some point in time a new record is <strong>INSERT</strong>ed into a database table. Then, when time goes by, some of it&#8217;s properties (columns) will be <strong>UPDATE</strong>d. Until at some point later somebody decides to <strong>DELETE</strong> it from the database and therefore remove all it&#8217;s tracks from this world.</p>
<p>Let&#8217;s investigate this simple fact of what&#8217;s actually happening here a little bit deeper by reconnecting the lifecycle of information about the world with the lifecycle of the data living in the database. Databases regularly don&#8217;t store arbitrary data, but try to reflect some aspects of the real world. As a sample, I suggest to think of a civil registry&#8217;s database storing the spouses, children and all their places of living for a certain countries citizens. Let&#8217;s e.g. focus on one of those persons &#8211; let&#8217;s call her <strong>Mrs. Sometimes</strong> &#8211; and her place of living: some (probably short) time after her birth this fact of birth will be reflected in the database by INSERTing information about herself and INSERTing her first place of living. Later on, Mrs Sometime&#8217;s place of living will potentially change several times. Maintaining this databases address table therefore means to try best to reflect the real status of this single aspect of the world: where do my fellow citizens actually live? If somebody moves we UPDATE, if somebody dies, we DELETE.</p>
<p><strong>To sum it up until here:</strong></p>
<blockquote><p>The basic data manipulation operations provided by a typical relational database management system (<strong>INSERT, UPDATE, DELETE</strong>) reflect the natural lifecycle of the recorded aspects of the (ever changing) outside world. The database we maintain by applying those operations tries it&#8217;s best to reflect the current status of the outside world. But regularly, it will take some time until the information finds its way into the database. And sometimes this will never happen &#8211; and the data inside the database will for some reason be plain wrong, meaning: not correctly reflecting the true facts of the outside world.</p></blockquote>
<p>I used some important terms in the last paragraph which will propably occupy me for a longer time: I said the database reflects the <strong>current status</strong> (because outdated information is UPDATEd or DELETEd). I also said there typically is a <strong>time gap</strong> between a status change in the outside world (e.g. somebody moves) and the status change in the database (here e.g. correctly reflecting this move). And I said some database data may be <strong>wrong data</strong>. </p>
<p>To finish this post I want to deduct from this some of the typical user questions our simple-sample-database cannot answer:</p>
<ul>
<li>Where did Mrs. Sometimes live five years ago?</li>
<li>When did Mrs. Sometimes move the last time?</li>
<li>From when on did the Database reflect this fact?</li>
<li>What did we know about Mrs. Sometimes&#8217;s first place of living some weeks after her birth?</li>
<li>And what do we know about it today? When was it discovered that the original information about Mrs Sometimes&#8217;s first place of living was manipulated by her father and therefore corrected later on?</li>
<li>And where can we write down the fact that Mrs&#8217; Sometimes just called us and told us that she will definitely move in two month and already wants to drop this information?</li>
</ul>
<p>Unfortunately the necessity to ask such questions, such &#8220;use cases&#8221; are not uncommon at all. In fact they are strongly <strong>typical</strong> and appear in many flavours. But they are typically not thought of from the beginning of an average application development on. To be continued.</p>

<img src="http://feeds.feedburner.com/~r/TryItAndCatchItFinally/~4/alZAN3R-sqE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://developing.schimak.at/2009/11/about-the-lifecycle-of-data/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://developing.schimak.at/2009/11/about-the-lifecycle-of-data/</feedburner:origLink></item>
		<item>
		<title>Playing through GWT with IntelliJ IDEA</title>
		<link>http://feedproxy.google.com/~r/TryItAndCatchItFinally/~3/Y2CxXJoVSGU/</link>
		<comments>http://developing.schimak.at/2009/11/playing-through-gwt-with-intellij-idea/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 09:00:07 +0000</pubDate>
		<dc:creator>Martin Schimak</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://developing.schimak.at/?p=187</guid>
		<description><![CDATA[
This is the simple and at the same time bold promise of Googles Web Toolkit (GWT) on it&#8217;s relatively decent web housing on Google Code: 
Developers can spend 90% of their time working around browser quirks. In addition, building, reusing, and maintaining large JavaScript code bases and AJAX components can be difficult and fragile. Google [...]]]></description>
			<content:encoded><![CDATA[
<p>This is the simple and at the same time bold promise of Googles <strong>Web Toolkit</strong> (<strong>GWT</strong>) on it&#8217;s relatively decent web housing on <a href="http://code.google.com/intl/de-DE/webtoolkit/">Google Code</a>: </p>
<blockquote><p>Developers can spend 90% of their time working around browser quirks. In addition, building, reusing, and maintaining large JavaScript code bases and AJAX components can be difficult and fragile. Google Web Toolkit (GWT), especially when combined with the Google Plugin for Eclipse, eases this burden by allowing developers to quickly build and maintain complex yet highly performant JavaScript front-end applications in the Java programming language.</p></blockquote>
<p>As a first step of my personal convergence to this technology, I want to play through the official &#8220;StockWatcher&#8221; <a href="http://code.google.com/intl/de-DE/webtoolkit/tutorials/1.6/gettingstarted.html">Getting Started Tutorial</a> at their Website. I&#8217;m really curious, what I will like and what I maybe won&#8217;t like at all, especially when comparing my then freshly developed GWT awareness with the still cloudy but at the same time already demanding requirements I have in my mind with respect to <a href="http://developing.schimak.at/2009/08/best-of-breed-ui-technologies/">Best-Of-Breed UI Technologies</a>.</p>
<p>I don&#8217;t want to use Eclipse as suggested and recommended overthere, but <a href="http://www.jetbrains.com/idea">IntelliJ IDEA</a>, so maybe I can even deliver some additional value compared to the &#8220;official&#8221; tutorial. As Information about IDEAs GWT Support I found their <a href="http://www.jetbrains.com/idea/training/demos/GWT.html">1-2-3 Video GWT Tutorial</a>.</p>
<h2>Step 1: Creating a GWT Project <span style="font-size: 9px">(Please see the <a href="http://code.google.com/intl/de-DE/webtoolkit/tutorials/1.6/create.html">Official Tutorial</a>, too.)</span></h2>
<ol>
<li><a href="http://code.google.com/intl/de-DE/webtoolkit/gettingstarted.html#Install">Install Google Web Toolkit</a></li>
<li>Right Click on your IntelliJ IDEA Java Project.</li>
<li>Select &#8216;Add Framework Support&#8230;&#8217;</li>
<li>Check &#8216;Google Web Toolkit&#8217; and select proper Installation Path</li>
<li>Create a Java Package called &#8216;com.google.gwt.sample.stockwatcher&#8217;</li>
<li>Right click your Package, select &#8216;New&#8230;/Google Web Toolkit/GWT Module&#8217; and enter &#8216;StockWatcher&#8217; as Name.</li>
<li>Right click your Package, select &#8216;New&#8230;/Google Web Toolkit/GWT Remote Service&#8217; and enter &#8216;Greeting&#8217; as Name.</li>
<li>If you happen to use Mac OS X, you must edit the Project Settings to use a Java 1.5 runtime for GWT Hosted Mode.</li>
</ol>
<h2>Step 2: Designing the Application <span style="font-size: 9px">Please see the <a href="http://code.google.com/intl/de-DE/webtoolkit/tutorials/1.6/design.html">Official Tutorial</a></span></h2>
<h2>Step 3: Building the User Interface <span style="font-size: 9px">(Please see the <a href="http://code.google.com/intl/de-DE/webtoolkit/tutorials/1.6/buildui.html">Official Tutorial</a>, too.)</span></h2>
<ol>
<li> Basically this Step consists of editing the StockWatcher Class (which means implementing an EntryPoint Interface):
<pre class="brush: java;">
public class StockWatcher implements EntryPoint {

  private VerticalPanel mainPanel = new VerticalPanel();
  private FlexTable stocksFlexTable = new FlexTable();
  private HorizontalPanel addPanel = new HorizontalPanel();
  private TextBox newSymbolTextBox = new TextBox();
  private Button addStockButton = new Button(&quot;Add&quot;);
  private Label lastUpdatedLabel = new Label();

  /**
   * Entry point method.
   */
  public void onModuleLoad() {
    // Create table for stock data.
    stocksFlexTable.setText(0, 0, &quot;Symbol&quot;);
    stocksFlexTable.setText(0, 1, &quot;Price&quot;);
    stocksFlexTable.setText(0, 2, &quot;Change&quot;);
    stocksFlexTable.setText(0, 3, &quot;Remove&quot;);
    // Assemble Add Stock panel.
    addPanel.add(newSymbolTextBox);
    addPanel.add(addStockButton);
    // Assemble Main panel.
    mainPanel.add(stocksFlexTable);
    mainPanel.add(addPanel);
    mainPanel.add(lastUpdatedLabel);
    // Associate the Main panel with the HTML host page.
    RootPanel.get(&quot;stockList&quot;).add(mainPanel);
    // Move cursor focus to the input box.
    newSymbolTextBox.setFocus(true);
  }

}
</pre>
</li>
<li>Once you have this you can already startup your &#8220;hosted&#8221; Test UI by right-clicking your StockWatcher Class and selecting &#8216;Run StockWatcher&#8217;. Once your &#8216;Hosted Mode Browser&#8217; is running, it will reflect any Code Change you make after a Click on its &#8216;Refresh&#8217; Button.</li>
<li>One Remark: I had to increase my JRE heap size setting to 256MB first, by editing the Run/Edit Configurations (-Xmx256M) to get the Hosted Mode running.</li>
</ol>
<h2>Step 4: Managing Events on the Client <span style="font-size: 9px">Please see the <a href="http://code.google.com/intl/de-DE/webtoolkit/tutorials/1.6/manageevents.html">Official Tutorial</a></span></h2>
<h2>Step 5: Coding Functionality on the Client <span style="font-size: 9px">Please see the <a href="http://code.google.com/intl/de-DE/webtoolkit/tutorials/1.6/codeclient.html">Official Tutorial</a></span></h2>
<h2>Step 6: Managing Events on the Client <span style="font-size: 9px">(Please see the <a href="http://code.google.com/intl/de-DE/webtoolkit/tutorials/1.6/manageevents.html">Official Tutorial</a>, too.)</span></h2>
<p>After having successfully added the EventListeners (Step 4), the required Table Coding (Step 5) and played through the quite convincing Debugging Section (Section 6), my Class looks now looks like the following:</p>
<pre class="brush: java;">
public class StockWatcher implements EntryPoint {

    private VerticalPanel mainPanel = new VerticalPanel();
    private FlexTable stocksFlexTable = new FlexTable();
    private HorizontalPanel addPanel = new HorizontalPanel();
    private TextBox newSymbolTextBox = new TextBox();
    private Button addStockButton = new Button(&quot;Add&quot;);
    private Label lastUpdatedLabel = new Label();

    private static final int REFRESH_INTERVAL = 5000; // ms
    private ArrayList&lt;String&gt; stocks = new ArrayList&lt;String&gt;();

    public void onModuleLoad() {
        // Create table for stock data.
        stocksFlexTable.setText(0, 0, &quot;Symbol&quot;);
        stocksFlexTable.setText(0, 1, &quot;Price&quot;);
        stocksFlexTable.setText(0, 2, &quot;Change&quot;);
        stocksFlexTable.setText(0, 3, &quot;Remove&quot;);
        // Assemble Add Stock panel.
        addPanel.add(newSymbolTextBox);
        addPanel.add(addStockButton);
        // Assemble Main panel.
        mainPanel.add(stocksFlexTable);
        mainPanel.add(addPanel);
        mainPanel.add(lastUpdatedLabel);
        // Associate the Main panel with the HTML host page.
        RootPanel.get(&quot;stockList&quot;).add(mainPanel);
        // Move cursor focus to the input box.
        newSymbolTextBox.setFocus(true);
        // Setup timer to refresh list automatically.
         Timer refreshTimer = new Timer() {
           @Override
           public void run() {
             refreshWatchList();
           }
         };
         refreshTimer.scheduleRepeating(REFRESH_INTERVAL);
        // Listen for mouse events on the Add button.
        addStockButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                addStock();
            }
        });
        // Listen for keyboard events in the input box.
        newSymbolTextBox.addKeyPressHandler(new KeyPressHandler() {
            public void onKeyPress(KeyPressEvent event) {
                switch (event.getCharCode()) {
                    case KeyCodes.KEY_ENTER: addStock();
                }
            }
        });
    }

    private void addStock() {
        final String symbol = newSymbolTextBox.getText()
            .toUpperCase().trim();
        newSymbolTextBox.setFocus(true);
        // Stock code must be between 1 and 10 chars that
           are numbers, letters, or dots.
        if (!symbol.matches(&quot;^[0-9A-Z\\.]{1,10}$&quot;)) {
            Window.alert(&quot;'&quot; + symbol + &quot;' is not a valid symbol.&quot;);
            newSymbolTextBox.selectAll();
            return;
        }
        newSymbolTextBox.setText(&quot;&quot;);
        // Don't add the stock if it's already in the table.
        if (stocks.contains(symbol))
          return;
        // Add the stock to the table.
        int row = stocksFlexTable.getRowCount();
        stocks.add(symbol);
        stocksFlexTable.setText(row, 0, symbol);
        // Add a button to remove this stock from the table.
        Button removeStockButton = new Button(&quot;x&quot;);
        removeStockButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                int removedIndex = stocks.indexOf(symbol);
                stocks.remove(removedIndex);
                stocksFlexTable.removeRow(removedIndex + 1);
            }
        });
        stocksFlexTable.setWidget(row, 3, removeStockButton);
        // TODO Get the stock price.
        refreshWatchList();
    }

    private void refreshWatchList() {
        final double MAX_PRICE = 100.0; // $100.00
        final double MAX_PRICE_CHANGE = 0.02; // +/- 2%
        StockPrice[] prices = new StockPrice[stocks.size()];
        for (int i = 0; i &lt; stocks.size(); i++) {
            double price = Random.nextDouble() * MAX_PRICE;
            double change = price * MAX_PRICE_CHANGE
                * (Random.nextDouble() * 2.0 - 1.0);
            prices[i] = new StockPrice(stocks.get(i), price, change);
        }
        updateTable(prices);
    }

    private void updateTable(StockPrice price) {
        // Make sure the stock is still in the stock table.
        if (!stocks.contains(price.getSymbol())) {
          return;
        }
        int row = stocks.indexOf(price.getSymbol()) + 1;
        // Format the data in the Price and Change fields.
        String priceText = NumberFormat.getFormat(&quot;#,##0.00&quot;)
            .format(price.getPrice());
        NumberFormat changeFormat = NumberFormat
            .getFormat(&quot;+#,##0.00;-#,##0.00&quot;);
        String changeText = changeFormat.format(price.getChange());
        String changePercentText = changeFormat
            .format(price.getChangePercent());
        // Populate the Price and Change fields with new data.
        stocksFlexTable.setText(row, 1, priceText);
        stocksFlexTable.setText(row, 2, changeText + &quot; (&quot;
            + changePercentText + &quot;%)&quot;);
    }

    private void updateTable(StockPrice[] prices) {
        for (int i = 0; i &lt; prices.length; i++) {
            updateTable(prices[i]);
        }
        // Display timestamp showing last refresh.
        lastUpdatedLabel.setText(&quot;Last update : &quot; + DateTimeFormat
            .getMediumDateTimeFormat().format(new Date()));
    }

}
</pre>
<p>In addition to that I have some encapsulated functionality in a new StockPrice class:</p>
<pre class="brush: java;">
public class StockPrice {

    private String symbol;
    private double price;
    private double change;

    public StockPrice() {
    }

    public StockPrice(String symbol, double price, double change) {
        this.symbol = symbol;
        this.price = price;
        this.change = change;
    }

    public String getSymbol() {
        return this.symbol;
    }

    public double getPrice() {
        return this.price;
    }

    public double getChange() {
        return this.change;
    }

    public double getChangePercent() {
        return 100.0 * this.change / this.price;
    }

    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public void setChange(double change) {
        this.change = change;
    }

}
</pre>
<h2>Step 7: Applying Style <span style="font-size: 9px">(Please see the <a href="http://code.google.com/intl/de-DE/webtoolkit/tutorials/1.6/style.html">Official Tutorial</a>, too.)</span></h2>
<ul>
<li>CSS Stylesheets can be associated from within the HTML Host File or &#8211; preferably &#8211; from within the Module Definition XML:
<pre>
&lt;module&gt;
...
    &lt;inherits name="com.google.gwt.user.theme.dark.Dark"/&gt;
...
&lt;/module&gt;</pre>
</li>
<li>You can look up the name of the style rules (the CSS selector) for each widget by accessing the GWT API Reference via the <a href="http://code.google.com/webtoolkit/doc/1.6/RefWidgetGallery.html">Widget Gallery</a>.</li>
<li>Furthermore it&#8217;s possible to add custom HTML class names to the widgets and/or parts of it like e.g. Table Cells.</li>
</ul>
<h2>Step 8: Compiling a GWT Application <span style="font-size: 9px">(Please see the <a href="http://code.google.com/intl/de-DE/webtoolkit/tutorials/1.6/compile.html">Official Tutorial</a>, too.)</span></h2>

<img src="http://feeds.feedburner.com/~r/TryItAndCatchItFinally/~4/Y2CxXJoVSGU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://developing.schimak.at/2009/11/playing-through-gwt-with-intellij-idea/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://developing.schimak.at/2009/11/playing-through-gwt-with-intellij-idea/</feedburner:origLink></item>
		<item>
		<title>AOP really easy with Spring/AspectJ</title>
		<link>http://feedproxy.google.com/~r/TryItAndCatchItFinally/~3/cl0AY9fJ0Ac/</link>
		<comments>http://developing.schimak.at/2009/08/aop-really-easy-with-springaspectj/#comments</comments>
		<pubDate>Sat, 29 Aug 2009 13:28:49 +0000</pubDate>
		<dc:creator>Martin Schimak</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[AOP]]></category>
		<category><![CDATA[AspectJ]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://developing.schimak.at/?p=140</guid>
		<description><![CDATA[
Aspect-oriented programming (AOP) is a programming paradigm that increases modularity by enabling improved separation of concerns. While object oriented programming paradigms support encapsulation of concerns, some concerns defy these forms of implementation and are called crosscutting concerns because they &#8220;cut across&#8221; multiple abstractions in a program. Logging is a common example of a crosscutting concern [...]]]></description>
			<content:encoded><![CDATA[
<p>Aspect-oriented programming (AOP) is a programming paradigm that increases modularity by enabling improved separation of concerns. While object oriented programming paradigms support encapsulation of concerns, some concerns defy these forms of implementation and are called crosscutting concerns because they &#8220;cut across&#8221; multiple abstractions in a program. Logging is a common example of a crosscutting concern because a logging strategy necessarily affects every single logged part of the system. </p>
<p>For introducing AspectJ based AOP within the well-known Spring Framework, we just need a few lines of Spring Configuration</p>
<pre class="brush: xml;">
&lt;!-- Activating AspectJ in Spring Config --&gt;
&lt;aop:aspectj-autoproxy/&gt;

&lt;!-- Configuring the Bean declaring the Aspect --&gt;
&lt;bean id=&quot;testAspect&quot; class=&quot;spring.demo.TestAspect&quot;/&gt;

&lt;!-- Some Test Bean to demonstrate the Aspect Execution --&gt;
&lt;bean id=&quot;test&quot; class=&quot;spring.demo.Test&quot;/&gt;
</pre>
<p>plus: the Class declaring the Aspect, of course</p>
<pre class="brush: java;">
@Aspect
public class TestAspect {

    @Pointcut(&quot;execution(* *(..))&quot;)
    public void methodExecution() {}

    @Around(&quot;spring.demo.AspectJTest.TestAspect.methodExecution()&quot;)
    public Object doTrace(ProceedingJoinPoint pjp) throws Throwable {
        Log log = LogFactory.getLog(pjp.getSignature().getDeclaringType());
        Object retVal;
        log.info(&quot;Starting method &quot; + pjp.getSignature().toLongString());
        retVal = pjp.proceed();
        log.info(&quot;Ending method &quot; + pjp.getSignature().toLongString());
        log.info(&quot;Method returned &quot; + retVal);
        return retVal;
    }

}
</pre>
<p>As this Aspect triggers the <code>@Around</code> method on every method execution invoking the method <code>boolean doSomething(boolean)</code> on our Test Class</p>
<pre class="brush: java;">
public class Test {
    public boolean doSomething(boolean param) {
        LogFactory.getLog(getClass()).info(&quot;About to return &quot; + param);
        return param;
    }
}
</pre>
<p>will lead to something like the following sample output proving the execution of the <code>TestAspect.doTrace(...)</code> method:</p>
<pre class="brush: plain;">
Starting method public boolean spring.demo.Test.doSomething(boolean)
About to return true
Ending method public boolean spring.demo.Test.doSomething(boolean)
Method returned true
</pre>
<p>which is nice, actually. The Full Spring Guide on this can be found <a href="http://static.springsource.org/spring/docs/2.5.x/reference/aop.html">here</a></p>

<img src="http://feeds.feedburner.com/~r/TryItAndCatchItFinally/~4/cl0AY9fJ0Ac" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://developing.schimak.at/2009/08/aop-really-easy-with-springaspectj/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://developing.schimak.at/2009/08/aop-really-easy-with-springaspectj/</feedburner:origLink></item>
		<item>
		<title>Mac OS X Environment Variables</title>
		<link>http://feedproxy.google.com/~r/TryItAndCatchItFinally/~3/LRbqPFbJtE8/</link>
		<comments>http://developing.schimak.at/2009/08/mac-osx-environment-variables/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 14:47:44 +0000</pubDate>
		<dc:creator>Martin Schimak</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Environment]]></category>
		<category><![CDATA[Mac OS X]]></category>

		<guid isPermaLink="false">http://developing.schimak.at/?p=121</guid>
		<description><![CDATA[
Most of the time, Mac OS X programs do not use environment variables like the &#8220;PATH&#8221;. However, sometimes I use tools that require such Variables. Contrary to well known places to put this kind of information in a Unix Environment (like /etc/profile, /etc/bashrc, ~/.profile, or ~/.bashrc files) the recommended way of doing this is the [...]]]></description>
			<content:encoded><![CDATA[
<p>Most of the time, Mac OS X programs do not use environment variables like the &#8220;PATH&#8221;. However, sometimes I use tools that require such Variables. Contrary to well known places to put this kind of information in a Unix Environment (like /etc/profile, /etc/bashrc, ~/.profile, or ~/.bashrc files) the <a href="http://developer.apple.com/mac/library/qa/qa2001/qa1067.html">recommended way</a> of doing this is the following:</p>
<ol>
<li>Add the following File to your User Directory, if it does not already exist:<br />
    <code>~/.MacOSX/environment.plist</code>
    </li>
<li>Open it with some Text Editor and add the following XML Code<br />
    <code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
    &lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;</p>
<pre>&lt;plist version="1.0"&gt;
    &lt;dict/&gt;
&lt;/plist&gt;</pre>
<p></code></li>
<li>Open the File in the Finder and add beneath &#8220;Root&#8221; an Environment Variable with the Mac OSX Plist Editor.</li>
<li>Log off and on again.</li>
<li>Enjoy.</li>
</ol>

<img src="http://feeds.feedburner.com/~r/TryItAndCatchItFinally/~4/LRbqPFbJtE8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://developing.schimak.at/2009/08/mac-osx-environment-variables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://developing.schimak.at/2009/08/mac-osx-environment-variables/</feedburner:origLink></item>
	</channel>
</rss>
