<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>adc&#124;works &#187; Development</title>
	<atom:link href="http://www.adcworks.com/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.adcworks.com</link>
	<description></description>
	<lastBuildDate>Wed, 06 Jan 2010 15:47:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Checking if a UK date is in the past with PHP</title>
		<link>http://www.adcworks.com/2010/01/checking-if-a-uk-date-is-in-the-past-with-php/</link>
		<comments>http://www.adcworks.com/2010/01/checking-if-a-uk-date-is-in-the-past-with-php/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 15:21:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.adcworks.com/?p=57</guid>
		<description><![CDATA[The easiest way to check if a date is in the past with PHP is using strtotime but unfortunately it only understands US and Unix date formats, not the UK&#8217;s format d/m/Y. A UK date string therefore needs to be transformed first. You will need to use a regular expression to first validate that your]]></description>
			<content:encoded><![CDATA[<p>The easiest way to check if a date is in the past with PHP is using strtotime but unfortunately it only understands US and Unix date formats, not the UK&#8217;s format d/m/Y.</p>
<p>A UK date string therefore needs to be transformed first. You will need to use a regular expression to first <a href="http://www.google.com/search?hl=en&amp;q=uk+date+format+regex&amp;btnG=Search&amp;meta=&amp;aq=f&amp;oq=" target="_blank">validate that your UK date is valid.</a> I do not set this out here. Once you are sure you have a UK valid date string of the format d/m/Y, e.g. 01/02/2010 you can do the following:</p>
<pre class="brush: php">
// tests a uk date string for being in the past. time components will be midnight for test to work.
function is_uk_date_in_past($pre_validated_uk_date_string_no_time) {
    list($d, $m, $y) = explode(&#039;/&#039;, $pre_validated_uk_date_string_no_time);
    $today = strtotime(date(&quot;Y-m-d&quot;)); // we do not define today as time() as that will include the current time
    $given = strtotime(&quot;{$y}-{$m}-{$d}&quot;);
    return $given &gt;= $today;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.adcworks.com/2010/01/checking-if-a-uk-date-is-in-the-past-with-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code Igniter Date Validation</title>
		<link>http://www.adcworks.com/2009/04/code-igniter-date-validation/</link>
		<comments>http://www.adcworks.com/2009/04/code-igniter-date-validation/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 13:39:30 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Code Igniter]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.adcworks.com/?p=38</guid>
		<description><![CDATA[Those looking for a Code Igniter date validator rule can use the following custom validation. This is written for CI 1.7+ To use, copy the class below into your system/application/libraries folder named MY_Form_validation.php, then in your controller use it like any other rule. Oh, and this is the first version so if you do come]]></description>
			<content:encoded><![CDATA[<p>Those looking for a Code Igniter date validator rule can use the following custom validation. This is written for CI 1.7+</p>
<p>To use, copy the class below into your system/application/libraries folder named MY_Form_validation.php, then in your controller use it like any other rule.</p>
<p>Oh, and this is the first version so if you do come across bugs/requests let me know would you? <img src='http://www.adcworks.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Cheers.</p>
<h3>Form</h3>
<p>This validation rule validates an input text box only right now.</p>
<pre class="brush: php">
&lt;input type=&quot;text&quot; name=&quot;date&quot; value=&quot;&lt;?php echo set_value(&#039;date&#039;); ?&gt;&quot; size=&quot;10&quot; /&gt;
</pre>
<h3>Controller Usage</h3>
<p>UK</p>
<pre class="brush: php">
$this-&gt;form_validation-&gt;set_rules(&#039;date&#039;, &#039;date&#039;, &#039;trim|required|valid_date[d/m/y,/]&#039;);
</pre>
<p>US</p>
<pre class="brush: php">
$this-&gt;form_validation-&gt;set_rules(&#039;date&#039;, &#039;date&#039;, &#039;trim|required|valid_date[m/d/y,/]&#039;);
</pre>
<p>Database</p>
<pre class="brush: php">
$this-&gt;form_validation-&gt;set_rules(&#039;date&#039;, &#039;date&#039;, &#039;trim|required|valid_date[y-m-d,-]&#039;);
</pre>
<h3>The Code</h3>
<pre class="brush: php">
&lt;?php if (!defined(&#039;BASEPATH&#039;)) exit(&#039;No direct script access allowed&#039;);

class MY_Form_validation extends CI_Form_validation {

    function MY_Form_validation()
    {
        parent::CI_Form_validation();
    }

    /**
    * @desc Validates a date format
    * @params format,delimiter
    * e.g. d/m/y,/ or y-m-d,-
    */
    function valid_date($str, $params)
    {
        // setup
        $CI =&amp;amp;amp;amp;amp;amp; get_instance();
        $params = explode(&#039;,&#039;, $params);
        $delimiter = $params[1];
        $date_parts = explode($delimiter, $params[0]);

        // get the index (0, 1 or 2) for each part
        $di = $this-&gt;valid_date_part_index($date_parts, &#039;d&#039;);
        $mi = $this-&gt;valid_date_part_index($date_parts, &#039;m&#039;);
        $yi = $this-&gt;valid_date_part_index($date_parts, &#039;y&#039;);

        // regex setup
        $dre = &quot;(0?1|0?2|0?3|0?4|0?5|0?6|0?7|0?8|0?9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31)&quot;;
        $mre = &quot;(0?1|0?2|0?3|0?4|0?5|0?6|0?7|0?8|0?9|10|11|12)&quot;;
        $yre = &quot;([0-9]{4})&quot;;
        $red = &#039;\\&#039;.$delimiter; // escape delimiter for regex
        $rex = &quot;^[0]{$red}[1]{$red}[2]$&quot;;

        // do replacements at correct positions
        $rex = str_replace(&quot;[{$di}]&quot;, $dre, $rex);
        $rex = str_replace(&quot;[{$mi}]&quot;, $mre, $rex);
        $rex = str_replace(&quot;[{$yi}]&quot;, $yre, $rex);

        if (ereg($rex, $str, $matches)) {
            // skip 0 as it contains full match, check the date is logically valid
            if (checkdate($matches[$mi + 1], $matches[$di + 1], $matches[$yi + 1])) {
                return true;
            } else {
                // match but logically invalid
                $CI-&gt;form_validation-&gt;set_message(&#039;valid_date&#039;, &quot;The date is invalid.&quot;);
                return false;
            }
        } 

        // no match
        $CI-&gt;form_validation-&gt;set_message(&#039;valid_date&#039;, &quot;The date format is invalid. Use {$params[0]}&quot;);
        return false;
    }      

    function valid_date_part_index($parts, $search) {
        for ($i = 0; $i &lt;= count($parts); $i++) {
            if ($parts[$i] == $search) {
                return $i;
            }
        }
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.adcworks.com/2009/04/code-igniter-date-validation/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Facebook Friend Sex</title>
		<link>http://www.adcworks.com/2009/04/facebook-friend-sex/</link>
		<comments>http://www.adcworks.com/2009/04/facebook-friend-sex/#comments</comments>
		<pubDate>Fri, 17 Apr 2009 20:28:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Facebook]]></category>

		<guid isPermaLink="false">http://www.adcworks.com/?p=35</guid>
		<description><![CDATA[I updated my Friend Sex Facebook application today with an &#8220;invite friends&#8221; capability which has been requested by a number of users. Some small visual and textual changes were also included.]]></description>
			<content:encoded><![CDATA[<p>I updated my <a href="http://apps.facebook.com/friendsex" target="_blank">Friend Sex Facebook application</a> today with an &#8220;invite friends&#8221; capability which has been requested by a number of users. Some small visual and textual changes were also included.</p>
<p><img class="aligncenter size-full wp-image-36" title="friendsex" src="http://www.adcworks.com/wp-content/uploads/2009/04/friendsex.gif" alt="friendsex" width="234" height="352" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.adcworks.com/2009/04/facebook-friend-sex/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Uckers for Dream Build Play 2009</title>
		<link>http://www.adcworks.com/2009/04/uckers-for-dream-build-play-2009/</link>
		<comments>http://www.adcworks.com/2009/04/uckers-for-dream-build-play-2009/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 13:51:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Uckers]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://www.adcworks.com/?p=29</guid>
		<description><![CDATA[Last year I entered Dream Build Play with the board game Uckers. I didn&#8217;t win of course but it was great to take part and create a game. But there was so much more I wanted for the game and so I withheld it from the Community Games channel. Now Dream Build Play is back]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="aligncenter size-full wp-image-30" style="border: 0pt none;" title="uckers" src="http://www.adcworks.com/wp-content/uploads/2009/04/uckers.jpg" alt="uckers" width="180" height="74" /></p>
<p>Last year I entered <a href="http://www.dreambuildplay.com" target="_blank">Dream Build Play</a> with the board game <a href="/uckers/">Uckers</a>. I didn&#8217;t win of course but it was great to take part and create a game. But there was so much more I wanted for the game and so I withheld it from the Community Games channel.</p>
<p>Now Dream Build Play is back and my intention is to get those features into the game. Things like artifical intelligence and Live versus play are crucial for the entry this year (Uckers currently supports only 2 player local play) among other enhancements that will become clear as I update this blog towards August&#8217;s entry date.</p>
<p>In any case I aim to have Uckers on Community Games this autumn/fall.</p>
<p>Wish me luck, it&#8217;s going to be a long summer <img src='http://www.adcworks.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Keep up to date here and on the <a href="/uckers/">Uckers</a> page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adcworks.com/2009/04/uckers-for-dream-build-play-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP SoapClient Could Not Connect to Host</title>
		<link>http://www.adcworks.com/2008/04/php-soapclient-could-not-connect-to-host/</link>
		<comments>http://www.adcworks.com/2008/04/php-soapclient-could-not-connect-to-host/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 21:24:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://adcworks/?p=11</guid>
		<description><![CDATA[The Could Not Connect to Host error message when using PHP SoapClient can be a tricky sucker to trace the root of. There are varying responses across the internets to what may cause this problem such as firewalls and proxies. But there is one other thing you can check. Look through the WSDL for the]]></description>
			<content:encoded><![CDATA[<p>The Could Not Connect to Host error message when using PHP SoapClient can be a tricky sucker to trace the root of. There are varying responses across the internets to what may cause this problem such as firewalls and proxies.</p>
<p>But there is one other thing you can check. Look through the WSDL for the soap:address locations. You may find that a server name is given that the machine running your code does not have access to.</p>
<p>Take a look at the example below;</p>
<pre class="brush: xml">&lt;service name=&quot;SomeService&quot;&gt;
  &lt;port binding=&quot;tns:WebServiceBinding&quot; name=&quot;WebServicePort&quot;&gt;
    &lt;soap:address location=&quot;http://appserver3:8080/webservices/WebServiceEndPoint&quot;/&gt;
  &lt;/port&gt;
&lt;/service&gt;
</pre>
<p>I experienced the issue when deploying my code from my dev machine to a live server. I couldn&#8217;t understand why my dev machine was fine calling the web services and the live server was not.</p>
<p>That&#8217;s because I had forgotten that I had provided access to my dev machine in the early days of coding to the appserver3 server name by virtue of a hosts file entry. Looking in my hosts file revealed</p>
<p>123.123.123.123  appserver3</p>
<p>And this is what was missing on the live server.</p>
<p>So if you get this error and you just can&#8217;t figure it out, take a wander through the WSDL for location URLs that may not be accessible to the server running your code. If you have a server name rather than an IP as in the example above, then add a hosts file mapping to the IP and you&#8217;re away.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adcworks.com/2008/04/php-soapclient-could-not-connect-to-host/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Using XNA DrawableGameComponent</title>
		<link>http://www.adcworks.com/2008/04/using-xna-drawablegamecomponent/</link>
		<comments>http://www.adcworks.com/2008/04/using-xna-drawablegamecomponent/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 21:17:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://adcworks/?p=8</guid>
		<description><![CDATA[This post is for those thinking about using the DrawableGameComponent class in the XNA framework. I am going to demonstrate how you might use the class by using the example of dice. Project Files Download Dice.zip for the Visual Studio Express 2005 XNA 2.0 project files. Extract the zip, then run Dice.csproj to open the]]></description>
			<content:encoded><![CDATA[<p>This post is for those thinking about using the DrawableGameComponent class in the XNA framework.</p>
<p>I am going to demonstrate how you might use the class by using the example of dice.</p>
<p><img src="http://www.adcworks.com/repository/Dice.jpg" alt="" width="216" height="136" /></p>
<h2>Project Files</h2>
<p><a href="http://www.adcworks.com/downloads/Dice.zip">Download Dice.zip</a> for the Visual Studio Express 2005 XNA 2.0 project files. Extract the zip, then run Dice.csproj to open the project in VSE 2005. You can then just compile the project by pressing the play icon.</p>
<h2>DrawableGameComponent</h2>
<p>Dice are ideal for illustrating the DrawableGameComponent class because dice, even in the real-world, are reusable across many table games, and that&#8217;s really where DrawableGameComponent comes in handy.</p>
<p>The DrawableGameComponent provides the developer a nice structured way to create modular, self-contained and reusable game components. A component should by definition be able to be dropped into a game and with minimal wiring up, just work.</p>
<h2>Understanding the Source</h2>
<p>The way in which to use DrawableGameComponent is to extend it. By doing this, when we add our component to the game, the XNA framework will know how to call it properly.</p>
<p>The Dice class therefore is made to extend DrawableGameComponent. The constructor for DrawableGameComponent requires the Game instance to be passed, so we need to ensure our component class constructor receives the game instance in addition to any specific variables so that it may pass the game instance on to the superclass for instantiation.</p>
<p>In essence when creating a component, you will want to override 3 of the methods of the DrawableGameComponent superclass; LoadContent, Update and Draw. For beginners, LoadContent is a method in which we instantiate resources like graphics and sounds, Update is used to update game logic (and this is done per game loop cycle &#8211; which is fast), and Draw in which we paint stuff to the screen.</p>
<p>You will see in the Dice class that I have overridden these 3 methods using the override keyword in the method declarations.  Each of these methods as their last statement call the superclass&#8217;s version of the method to ensure the component is fully called.</p>
<p>A die has 6 faces, so I added 6 graphics files to represent each face of a die. These are added to the Content folder in the project. As such, within LoadContent, I am able to load them as Texture2D files.</p>
<p>A separate Die class represents a single die since the actual Dice class supports as many die instances as you want. In practice this will be 1 or 2, but hey, it&#8217;s all about extensibility!</p>
<p>The Die class contains a method for rolling the single die. It uses a static instance of Random to roll a random face between 1 and 6.</p>
<p>The Dice class also contains some logic methods. Roll iterates all the die instances and calls their Roll methods. And Total returns the sum of all die instance faces at the time of call.</p>
<h2>Using the Dice Component</h2>
<p>To use the Dice component, we need to add it to our main game instance. In Game1 we just have to add an instance of Dice to the Game.Components collection. Simple as that.</p>
<p>By doing this, each game update tick, the Dice component&#8217;s Update and Draw methods are called.</p>
<p>The Dice.Update method monitors the keyboard for presses of the Space Bar. This triggers a roll of the active die instances.</p>
<p>Dice.Draw draws the relevant Texture2D graphics for the active die instances.</p>
<p>In the project, I just draw out each die next to each other.</p>
<p>Keep pressing Space Bar and you will see the dice change as you roll them.#</p>
<h2>Final Words</h2>
<p>I hope this article was of use to some of you, particularly those starting out with XNA. The DrawableGameComponent method of encapsulating game logic is a really good pattern to follow.</p>
<p>Some of you may be wondering though &#8211; since the Dice class is constantly monitoring the Space Bar, when you add that to a real game, where you would want to block dice rolls until certain other events take place &#8211; how do you do that?</p>
<p>Well, you&#8217;d need additional wiring in that case. One idea might be to maintain a flag CanDiceRoll for example in the main game. The Dice.Update method would need to use a conditional block based on that flag to determine if it should roll. Suggestions from readers are welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adcworks.com/2008/04/using-xna-drawablegamecomponent/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Dynamic PDF generation with JasperReports, Struts and a database</title>
		<link>http://www.adcworks.com/2006/10/dynamic-pdf-generation-with-jasperreports-struts-and-a-database/</link>
		<comments>http://www.adcworks.com/2006/10/dynamic-pdf-generation-with-jasperreports-struts-and-a-database/#comments</comments>
		<pubDate>Sun, 15 Oct 2006 21:51:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[J2EE]]></category>

		<guid isPermaLink="false">http://adcworks/?p=24</guid>
		<description><![CDATA[Generating a dynamic PDF from a database with JasperReports and Struts A requirement appeared recently as part of a Purchase Ordering application to allow a user to dynamically generate a PDF copy of the final Purchase Order to send to the supplier. Taking a look around I stumbled rather fortunately upon an API called JasperReports]]></description>
			<content:encoded><![CDATA[<h2>Generating a dynamic PDF from a database with JasperReports and Struts</h2>
<p>			A requirement appeared recently as part of a Purchase Ordering application to allow a user to dynamically generate a PDF copy of the final Purchase Order to send to the supplier. Taking a look around I stumbled rather fortunately upon an API called JasperReports (JR). JasperReports is a powerful open source Java reporting tool that has the ability to deliver rich content onto the screen, to the printer or into PDF, HTML, XLS, CSV and XML files. This tutorial is aimed at the beginner JR user who is happy with J2EE web application development. It will show you how JR was used to deliver the requirement described and should convince you that it is a truly fantastic piece of kit.</p>
<h2>What we will be doing in 1 sentence</h2>
<p>You will define a report template using JR&#8217;s XML syntax and then bind data from a database into it and get a PDF sent back to a web browser.</p>
<h2>What will I need</h2>
<p>OK, you need a few bits of kit. Firstly, I hate to break it to you but I kind of cheated with defining the report template. See, thing is, you can write this manually, but I didn&#8217;t have time to learn the ins and outs of JR&#8217;s XML syntax, so I got hold of JasperAssistant, a brilliant Eclipse IDE plugin that allows a developer to visually draw their report for JR. If like me you use Eclipse, or indeed you just want to use this method for creating your report template, grab Eclipse and JasperAssistant. There is also another tool called iReport that does a similar thing without Eclipse but you&#8217;ll need to look at that yourself. So, you will need</p>
<ul>
<li>JasperReports &#8211; head to the Download section</li>
<li>Either JasperAssistant, iReports OR a willingness to learn the JR XML syntax for which there are many examples with the JR distribution. Whichever method you chose, I leave it to you to configure the environment &#8211; full instructions are available on each site.</li>
<li>A knowledge of J2EE web application development. In this tutorial I shall be using Struts but only in the slightest way to illustrate how to send the PDF back to the web user. You can do the same stuff with a plain old Servlet.</li>
</ul>
<h2>Creating the report template</h2>
<p>First of all, you need to think about what data your report needs to show. In my scenario, we are talking about a Purchase Ordering application. In this application is the master object called PurchaseOrder. A PurchaseOrder has at least one or more LineItem stored in a list collection. Each of these 2 objects have other attributes that reveal information, e.g the PuchaseOrder has a createdDate and orderId whereas a LineItem has a description and unitCost. These objects are persisted to a database. It is not really important how, it may be via a series of SQL statements or it may be via some Object Relational Mapping API such as Hibernate (which for the record, is how I have done it), but what matters is that you have code in place to save and fetch your particular application objects/data. Now, my report layout requires that the header contain master detail such as the created date and order id and then to list all the line items in a table below. Finally, some more master detail such as delivery address is required at the foot. JR divides up a report into a series of stacked bands from top to bottom, e.g title, header, detail and footer are names of some bands. In my case, I chose to use the header, detail and footer bands for the areas I have just mentioned.</p>
<h2>Parameters, fields and static text</h2>
<p>Using JasperAssistant, I was able to draw my report layout using guides and properties boxes. You may do the same or do it manually, but the main elements that I had to use were parameters, fields and static text. JR has a mechanism for binding a Map of data to a report. This is referred to as a parameter map. The idea being that the map element&#8217;s key is used for binding the map element&#8217;s value to the parameter defined in the report. For example, if I have an empty report with a parameter declaration orderId as follows:</p>
<pre class="brush: xml">
http://jasperreports.sourceforge.net/dtds/jasperreport.dtd&quot;&gt;
</pre>
<p>then I would need a corresponding Map</p>
<pre class="brush: java">
Map map = new HashMap();
map.put(orderId, &quot;12345&quot;);
</pre>
<p>I will show how you can bind this to the report later. In addition to the parameter map mechanism, you can also use something called a DataSource. You musn&#8217;t think a DataSource is a database necessarily like it is with an application server. A DataSource is an object that provides methods that can be called by the report in obtaining rows of data. For my purposes if you remember, I have a collection of LineItem elements inside my PurchaseOrder and I need to loop through them outputting to a table in my report. The way I achieved this was by implementing JR&#8217;s DataSource interface JRDataSource. This interface requires an implementation provide methods;</p>
<pre class="brush: xml">
public boolean next() throws JRException;
public Object getFieldValue(JRField field) throws JRException;
</pre>
<p>In your report, you must define fields in the detail band. When the report is run together with the custom implementation, JR will automatically keep calling next and then attempt to bind each field in the detail band to a call to getFieldValue(JRField field).</p>
<p>Since my implementation of JRDataSource will return operation on a collection of LineItem I have named my DataSource LineItemDataSource. It has 2 class variables; private List data; private int index; Which is an internal data List to use (which I will populate with LineItem objects later), and the index allows us to know at which position we are in iteration of the List. That&#8217;s why you need to use List, because it is indexed and has methods for getting elements at certain indexes.</p>
<p>I also have an add(LineItem lineItem) for adding LineItem objects. Now, the implementation of next is quite simple:</p>
<pre class="brush: xml">
public boolean next() throws JRException {
  index++;
  return (index &lt; data.size());
}
</pre>
<p>I increase the index by 1, and then return a boolean as to whether the index is still within the List&#8217;s bounds. JR will use this to determine if any more binding to fields in the detail band is required. Finally, the implementation of getFieldValue. First, let&#8217;s show you how to define iterating fields in your report template. You need to define fields in your detail band like this:</p>
<pre class="brush: xml">
&lt; ![CDATA[$F{getItemName}]]&gt; &lt; ![CDATA[$F{getItemCost}]]&gt;
</pre>
<p>The detail band is iterated over using the custom DataSource implementation which I will show you in a moment. What is important is that you declare your textField elements along with their child textFieldExpression elements. The textFieldExpression tells the JR binding process what fields (by name) to look for in the DataSource. You can call these whatever you like, but as you can see in my case, I have decided to call them getXXX like a traditional bean accessor. Why have I done this? Well, because my LineItem object has matching accessor methods. So now let&#8217;s return to the custom DataSource implementation of getFieldValue. Here is the full listing:</p>
<pre class="brush: xml">
public Object getFieldValue(JRField field) throws JRException {
  LineItem lineItem = (LineItem) data.get(index);
  Object value = null;
  try {
    Object[] args = {};
    Class[] paramTypes = {};
    Class lineItemClass = lineItem.getClass();
    Method getMethod = lineItemClass.getDeclaredMethod(field.getName(), paramTypes);
    value = &quot;&quot; + getMethod.invoke(lineItem, args);
  } catch (Exception e) {
    throw new JRException(e.getMessage());
  }
  return value;
}
</pre>
<p>Clever huh? You don&#8217;t have to do it like this, but I have decided to use Java Reflection in order to dynamically call the appropriate LineItem method for the JRField parameter. That is why I named my textFieldExpression elements with getXXX. So, now if I were ever to add a new attribute to LineItem that I wanted in my report, I only need add it to LineItem with the accessors, and then into the report. I can leave my custom DataSource alone. One last note, I have defined all my fields as String even through my LineItem has attributes of float, int, Calendar. I am not really bothered that the report uses correct data types, but you can do that if you want, just set it up with your fields.</p>
<h2>Putting it all together</h2>
<p>So, you have hopefully got an idea about how JR works, particularly for my Purchase Order scenario. You should understand that a report template is defined by you either manually or using an editor like JasperAssistant. You will also appreciate 2 ways in which you can bind data to this report through parameters and fields. Furthermore, you have seen a clever way to use both methods in binding a master object with internal collection of elements to a report template. So now you probably want to see how to get the PDF back to the user. Well, remember that I am using a web application here but you don&#8217;t necessarily need to. First of all, I need to load my PurchaseOrder with it&#8217;s collection. You can do this however you like. In my case, I use Hibernate to load the object out of the database. PurchaseOrder po = poDAO.load(id); Now, I need to setup a parameter map for the master details</p>
<pre class="brush: xml">
Map parameterMap = new HashMap();
parameterMap.put(&quot;orderId&quot;, po.getOrderId());
parameterMap.put(&quot;createdDate&quot;, convertToDateString(po.getCreated()));
parameterMap.put(&quot;deliveryAddress&quot;, po.getDeliveryAddress());
</pre>
<p>There are a lot more! But this will do. Finally, I need to add my LineItem collection to my custom DataSource LineItemDataSource</p>
<pre class="brush: xml">
LineItemDataSource lineItemDataSource = new LineItemDataSource(po.getLineItems());
</pre>
<p>And last of all, let&#8217;s setup the response to the browser, and bind the parameter map and custom DataSource.</p>
<pre class="brush: xml">
response.setContentType(&quot;application/pdf&quot;);
response.addHeader(
  &quot;Content-Disposition&quot;,
  &quot;attachment; filename=PO - &quot; + po.getReference() + &quot;.pdf&quot;);

try {
  JasperRunManager.runReportToPdfStream( getClass().getClassLoader().getResourceAsStream( &quot;com/mycomp/po/pof.jasper&quot;), response.getOutputStream(), parameters, lineItemDataSource );
} catch (Exception e) {
  e.printStackTrace(System.out);
  logger.error(e);
}
</pre>
<p>Right, so I have used just one of the many ways in which you can bind to the report. You will of course need to find out how to compile your report template. When you author your template it is in .jrxml format and this needs to be compiled into a .jasper file which you can do either automatically with JasperAssistant, or manually with bundled tools with JR. In my example here, the compiled report is located in the class struture and I dynamically load it as an InputStream as required by the runReportToPdfStream method.</p>
<p>You should examine the JR API for all the other alternatives including running PDFs to file and even doing HTML output rather than PDF. In an application you would need to use slightly different calls that can be found in the JR API also. Some of you have asked how to send the result direct to the browser. Well, that&#8217;s easy &#8211; the code above forces a Save to Disk for the PDF by using the content-disposition header, so just comment out the response.addHeader call</p>
<pre class="brush: xml">
/* comment the save to disk feature out so that the pdf goes straight to the browser response.addHeader(&quot;Content-Disposition&quot;, &quot;attachment; filename=PO - &quot; + po.getReference() + &quot;.pdf&quot;); */
</pre>
<h2>Conclusion</h2>
<p>This tutorial has covered some specific aspects of the fantastic JasperReports API that may or may not be suitable for your own projects. I hope if nothing else, it provides an insight into one way of using the API or grounds you in the basics. There is so much more to JR that I have not used myself so take time once you get the idea to look at the bundled examples and API to make sure you are making the right choices.</p>
<p>JasperAssistant was an invaluable piece of kit for this job. It is quite tough getting to grips with the report template XML syntax, especially when your report needs pixel perfect alignment and so fourth. I did not go into a great deal of depth with layout elements like boxes and lines, but I have used them to draw the table boundaries around my detail LineItem band. Good luck, and if this article was helpful or not, leave a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.adcworks.com/2006/10/dynamic-pdf-generation-with-jasperreports-struts-and-a-database/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
