<?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>AMIS Technology Blog</title>
	<atom:link href="http://technology.amis.nl/feed/" rel="self" type="application/rss+xml" />
	<link>http://technology.amis.nl</link>
	<description></description>
	<lastBuildDate>Sat, 15 Jun 2013 14:57:43 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Automatic deployment .ear file to Oracle Application Server 10.1.3 (OAS) with Ant tasks</title>
		<link>http://technology.amis.nl/2013/06/12/automatic-deployment-ear-file-to-oracle-application-server-10-1-3-oas-with-ant-tasks/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=automatic-deployment-ear-file-to-oracle-application-server-10-1-3-oas-with-ant-tasks</link>
		<comments>http://technology.amis.nl/2013/06/12/automatic-deployment-ear-file-to-oracle-application-server-10-1-3-oas-with-ant-tasks/#comments</comments>
		<pubDate>Wed, 12 Jun 2013 21:08:31 +0000</pubDate>
		<dc:creator>Betty van Dongen</dc:creator>
				<category><![CDATA[ADF & JHeadstart]]></category>
		<category><![CDATA[AMIS]]></category>
		<category><![CDATA[J(2)EE/Java]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Java, JEE, OAS and WebLogic Server]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Oracle Development Tools]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web/Java]]></category>
		<category><![CDATA[adf]]></category>
		<category><![CDATA[adf 10g]]></category>
		<category><![CDATA[ant]]></category>
		<category><![CDATA[Ant target]]></category>
		<category><![CDATA[Ant tasks]]></category>
		<category><![CDATA[automatic]]></category>
		<category><![CDATA[binding module]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[build.xml]]></category>
		<category><![CDATA[context root]]></category>
		<category><![CDATA[deploy]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[ear]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[instance name]]></category>
		<category><![CDATA[OAS]]></category>
		<category><![CDATA[oc4j]]></category>
		<category><![CDATA[opmnPort]]></category>
		<category><![CDATA[Oracle Application Server]]></category>
		<category><![CDATA[redeploy]]></category>
		<category><![CDATA[redeployment]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[start]]></category>
		<category><![CDATA[stop]]></category>
		<category><![CDATA[web application]]></category>

		<guid isPermaLink="false">http://technology.amis.nl/?p=23360</guid>
		<description><![CDATA[In this post I would like to share an example how to deploy an .ear file with an Ant script to the Oracle Application Server 10.1.3 (OAS). Automatic deployment can help improve the release process. First of all because manual deployment usually costs time of the developers. Especially the lead time  [...]]]></description>
				<content:encoded><![CDATA[<p>In this post I would like to share an example how to deploy an .ear file with an Ant script to the Oracle Application Server 10.1.3 (OAS). Automatic deployment can help improve the release process. First of all because manual deployment usually costs time of the developers. Especially the lead time will be long if the uploading of the .ear file to the  server takes a long time. And mistakes made with manual deployment can cause quite some fixing time.</p>
<p>The Oracle documentation describes the use of Ant tasks for automatic deployment to the OAS. For more information on Ant tasks you can find an URL at the end of this post to the online Oracle documentation for the OAS, version 10.1.3.<br />
Versions 10.1.2 and earlier of the OAS have a different method for automatic deployment of the .ear to the server. This happens through a &#8216;Oc4jDcmServletAPI&#8217; and will not be discussed here.</p>
<p>Below you will find an example script regarding the use of Ant tasks:</p>
<p>&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;windows-1252&#8243; ?&gt;<br />
&lt;project name=&#8221;XXX&#8221; default=&#8221;redeploy&#8221; basedir=&#8221;.&#8221; xmlns:oracle=&#8221;antlib:oracle&#8221;&gt;<br />
 &lt;property name=&#8221;ear.dir&#8221;  value=&#8221;${basedir}&#8221;/&gt;</p>
<p> &lt;target name=&#8221;stop-app&#8221;&gt;<br />
  &lt;echo message=&#8221;Stopping the application&#8221;/&gt;<br />
  &lt;<b>oracle:stop</b> deployerUri=&#8221;${deployer.uri}&#8221; userId=&#8221;${oc4j.admin.user}&#8221;<br />
  password=&#8221;${oc4j.admin.password}&#8221; deploymentName=&#8221;${app.name}&#8221;/&gt;<br />
 &lt;/target&gt;</p>
<p> &lt;target name=&#8221;start-app&#8221;&gt;<br />
  &lt;echo message=&#8221;Starting the application&#8221;/&gt;<br />
  &lt;<b>oracle:start</b> deployerUri=&#8221;${deployer.uri}&#8221; userId=&#8221;${oc4j.admin.user}&#8221;<br />
  password=&#8221;${oc4j.admin.password}&#8221; deploymentName=&#8221;${app.name}&#8221;/&gt;<br />
 &lt;/target&gt;</p>
<p> &lt;target name=&#8221;undeploy-ear&#8221;&gt;<br />
  &lt;echo message=&#8221;Undeploying the application module deployment (ear) file&#8221;/&gt;<br />
  &lt;<b>oracle:undeploy</b> deployerUri=&#8221;${deployer.uri}&#8221; userId=&#8221;${oc4j.admin.user}&#8221;<br />
  password=&#8221;${oc4j.admin.password}&#8221; deploymentName=&#8221;${app.name}&#8221;<br />
  logFile=&#8221;${basedir}/undeploy-ear.log&#8221;/&gt;<br />
 &lt;/target&gt;</p>
<p> &lt;target name=&#8221;deploy-ear&#8221;&gt;<br />
  &lt;echo message=&#8221;Deploying the application module deployment (ear) file&#8221;/&gt;<br />
  &lt;<b>oracle:deploy</b> deployerUri=&#8221;${deployer.uri}&#8221; userId=&#8221;${oc4j.admin.user}&#8221;<br />
  password=&#8221;${oc4j.admin.password}&#8221; file=&#8221;${basedir}/${ear.filename}&#8221;<br />
  deploymentName=&#8221;${app.name}&#8221; bindAllWebApps=&#8221;default-web-site&#8221;<br />
  contextRoot=&#8221;${context.root}&#8221; logFile=&#8221;${basedir}/deploy-ear.log&#8221;/&gt;<br />
  &lt;<b>oracle:bindWebApp</b> deployerUri=&#8221;${deployer.uri}&#8221; userId=&#8221;${oc4j.admin.user}&#8221;<br />
  password=&#8221;${oc4j.admin.password}&#8221; deploymentName=&#8221;${app.name}&#8221;<br />
  webModule=&#8221;${war.filename}&#8221; webSiteName=&#8221;${oc4j.binding.module}&#8221;<br />
  contextRoot=&#8221;${context.root}&#8221;/&gt;<br />
 &lt;/target&gt;</p>
<p> &lt;target name=&#8221;redeploy&#8221;&gt;<br />
  &lt;input message=&#8221;Which release number are you deploying?&#8221; addproperty=&#8221;ear.version&#8221; /&gt;<br />
  &lt;input message=&#8221;To which environment are you deploying? &#8221; addproperty=&#8221;deploy.environment&#8221;/&gt;</p>
<p>  &lt;property name=&#8221;ear.location&#8221; value=&#8221;&lt;repository&gt; /${ear.version}/&#8221;/&gt;<br />
  &lt;property name=&#8221;ear.filename&#8221; value=&#8221; ear-${ear.version}.ear&#8221;/&gt;<br />
  &lt;property name=&#8221;war.filename&#8221; value=&#8221;viewController-${ear.version}&#8221;/&gt;</p>
<p>  &lt;get src=&#8221;${ear.location}${ear.filename}&#8221; dest=&#8221;${basedir}/${ear.filename}&#8221;/&gt;</p>
<p>  &lt;property file=&#8221;deploy_${deploy.environment}.properties&#8221;/&gt;</p>
<p>  &lt;ant target=&#8221;undeploy-ear&#8221;/&gt;<br />
  &lt;ant target=&#8221;deploy-ear&#8221;/&gt;<br />
  &lt;ant target=&#8221;stop-app&#8221;/&gt;<br />
  &lt;ant target=&#8221;start-app&#8221;/&gt;</p>
<p>  &lt;delete file=&#8221;${basedir}/${ear.filename}&#8221;/&gt;<br />
 &lt;/target&gt;<br />
&lt;/project&gt;</p>
<p><b>The code explained</b></p>
<p>In this example there are a couple of  preconditions. The released ear is to be found in the project repository and needs to be download from there. This example also took into account that you may want to redo a deployment, for example. Therefore the script doesn&#8217;t deploy the ear automatically after a build, but you can manually start the script and choose which released ear you want to deploy to which environment.  The following bullets explain the Ant script:</p>
<ol>
<li>The script contains Ant targets per action (stop, start, undeploy, deploy).</li>
<li>&#8216;redeploy&#8217; is the default target if the script is executed. This target actually executes all the steps to reploy the ear on the OAS:
<ol>
<li>input is asked which version needs to be deployed</li>
<li>input is asked to which environment needs to be deployed</li>
<li>the right ear is downloaded from the repository to the local deployment directory</li>
<li>the current deployment get undeployed from the right OAS</li>
<li>the new ear gets deployed to the right OAS, to the right OC4J instance</li>
<li>the OC4J instance gets stopped</li>
<li>the OC4J instance gets started</li>
<li>the new ear is removed from the deployment directory</li>
</ol>
</li>
<li>In  the script properties of the chosen environment are being used, these are collected from the properties file in the deployment directory:</li>
</ol>
<p><b>deploy_&lt;environment&gt;.properties:</b></p>
<p># The JSR88 deployer URIs. Valid URIs are:<br />
# 1- Oracle Application Server Cluster URI::<br />
#   deployer:cluster:opmn://opmnHost[:opmnPort]/oc4jInstanceName<br />
# 2- Oracle Application Server Single Instance URI:<br />
#   deployer:oc4j:opmn://opmnHost[:opmnPort]/oc4jInstanceName<br />
#   deployer:oc4j:opmn://opmnHost[:opmnPort]/asInstanceName/oc4jInstanceName<br />
# 3- OC4J URI:<br />
#   deployer:oc4j:[host]:[rmiPort]<br />
deployer.uri=deployer:oc4j:opmn://&lt;host&gt;:&lt;6003&gt;/&lt; iASInstanceName&gt;/&lt;OASInstanceName &gt;</p>
<p># The administrative login name for the target OC4J instance<br />
oc4j.admin.user=oc4jadmin</p>
<p># The administrative password for the target OC4J instance<br />
oc4j.admin.password=&lt;password&gt;</p>
<p># The application name within the target OC4J instance<br />
app.name=&lt;application_name&gt;</p>
<p># The context root of the OC4J application (including the &#8216;/&#8217;)<br />
context.root=/&lt;context-root&gt;</p>
<p># The web site to which the deployed web modules are bound<br />
oc4j.binding.module=default-web-site</p>
<p>It can be a bit of a search as to fill in the right properties. Therefore I would like to provide some images as a tool to find the right properties in the OAS Enterprise Manager.</p>
<table border="0" cellspacing="0" cellpadding="0">
<thead>
<tr>
<td valign="top" width="110"><b>Parameter</b></td>
<td valign="top" width="395"><b>Description</b></td>
<td valign="top" width="130"><b>Image</b></td>
</tr>
</thead>
<tbody>
<tr>
<td valign="top" width="133">host</td>
<td valign="top" width="362">The host name of the Oracle Application Server node within the  cluster.</td>
<td valign="top" width="144">Image 1, nr. 1</td>
</tr>
<tr>
<td valign="top" width="133">iASInstanceName</td>
<td valign="top" width="362">The name of the Oracle Application Server instance.</td>
<td valign="top" width="144">Image 1, nr. 2</td>
</tr>
<tr>
<td valign="top" width="133">opmnPort</td>
<td valign="top" width="362">The OPMN request port.</td>
<td valign="top" width="144">Image 2</td>
</tr>
<tr>
<td valign="top" width="133">OASInstanceName</td>
<td valign="top" width="362">The name of the OC4J instance.</td>
<td valign="top" width="144">Image 3, nr. 1</td>
</tr>
<tr>
<td valign="top" width="133">application name</td>
<td valign="top" width="362">The name of the web application.</td>
<td valign="top" width="144">Image 3, nr. 2</td>
</tr>
<tr>
<td valign="top" width="133">context root</td>
<td valign="top" width="362">The context root indicates the context path of the web application.</td>
<td valign="top" width="144">Image 3, nr. 3</td>
</tr>
</tbody>
</table>
<div id="attachment_23397" class="wp-caption alignleft" style="width: 778px"><a href="http://technology.amis.nl/wp-content/uploads/2013/06/OAS_Home_midtier_with_rem3.png"><img src="http://technology.amis.nl/wp-content/uploads/2013/06/OAS_Home_midtier_with_rem3-1024x247.png" alt="Image 1" width="768" height="186" class="size-large wp-image-23397" /></a><p class="wp-caption-text">Image 1</p></div>
<div id="attachment_23429" class="wp-caption alignleft" style="width: 778px"><a href="http://technology.amis.nl/wp-content/uploads/2013/06/OAS_Runtime_ports_with_rem.png"><img src="http://technology.amis.nl/wp-content/uploads/2013/06/OAS_Runtime_ports_with_rem-1024x286.png" alt="Image 2" width="768" height="215" class="size-large wp-image-23429" /></a><p class="wp-caption-text">Image 2</p></div>
<div id="attachment_23430" class="wp-caption alignleft" style="width: 778px"><a href="http://technology.amis.nl/wp-content/uploads/2013/06/OAS_applications_contextroot_with_rem2.png"><img src="http://technology.amis.nl/wp-content/uploads/2013/06/OAS_applications_contextroot_with_rem2-1024x227.png" alt="Image 3" width="768" height="171" class="size-large wp-image-23430" /></a><p class="wp-caption-text">Image 3</p></div>
<p>When running the Ant script, be aware that the OC4J Ant tasks utilize the ant installation that is shipped with the local JDeveloper 10 installation. For one there has to be a system variable ANT_HOME that points to the ant home in the JDeveloper installation (for example C:\JDeveloperADF10\ant). As a second the system variable PATH needs to contain the path to the ..\ant\bin directory of the local JDeveloper 10 installation (for example C:\JDeveloperADF10\ant\bin). Of course this can also be scripted in the command file to start the Ant script.</p>
<p><b>Oracle Documentation</b><br />
De following URL guides you to the Oracle documentation &#8220;Oracle® Containers for J2EE Deployment Guide 10g Release 3 (10.1.3)&#8221;. This documentation contains a chapter about the method used here: &#8220;<a href="http://docs.oracle.com/cd/B25221_05/web.1013/b14431/anttasks.htm#BEIGEEID">Deploying with the OC4J Ant Tasks&#8221;</a>:</p>
<p><a href="http://docs.oracle.com/cd/B25221_05/web.1013/b14431/toc.htm">http://docs.oracle.com/cd/B25221_05/web.1013/b14431/toc.htm</a></p>
]]></content:encoded>
			<wfw:commentRss>http://technology.amis.nl/2013/06/12/automatic-deployment-ear-file-to-oracle-application-server-10-1-3-oas-with-ant-tasks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using AutoLayout in iOS</title>
		<link>http://technology.amis.nl/2013/06/07/autolayout/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=autolayout</link>
		<comments>http://technology.amis.nl/2013/06/07/autolayout/#comments</comments>
		<pubDate>Fri, 07 Jun 2013 09:21:39 +0000</pubDate>
		<dc:creator>Rutger van Iperen</dc:creator>
				<category><![CDATA[AMIS]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[NSAutoLayout]]></category>
		<category><![CDATA[NSConstraint]]></category>
		<category><![CDATA[VisualFormatLanguage]]></category>

		<guid isPermaLink="false">http://technology.amis.nl/?p=23337</guid>
		<description><![CDATA[Like many iOS developers I did my sharing of trying out AutoLayout after it was introduced last year. And like many of these developers I ran into a fair share of trouble. It was not until Cessare Rochi clarified things in his session &#8216;AutoLayout, oh boy&#8217; at mdevcon that I finally started finding  [...]]]></description>
				<content:encoded><![CDATA[<p>Like many iOS developers I did my sharing of trying out AutoLayout after it was introduced last year. And like many of these developers I ran into a fair share of trouble. It was not until Cessare Rochi clarified things in his session &#8216;AutoLayout, oh boy&#8217; at mdevcon that I finally started finding my way around AutoLayout a bit.</p>
<p>First of, the consensus seems to be: do not use Interface Builder! IB gives you all kinds of challenges surrounding AutoLayout. Everyone has their own reasons for this but in short, when you use AutoLayout in code/manually, you are actually in control. So then how do we do this?</p>
<p><span id="more-23337"></span></p>
<p>Apple has given us a nice, albeit somewhat lenghty way of setting these constraints:</p>
<pre class="wp-code-highlight prettyprint">[NSLayoutConstraint constraintWithItem:label
                             attribute:NSLayoutAttributeCenterX 
                             relatedBy:NSLayoutRelationEqual 
                                toItem:tab
                             attribute:NSLayoutAttributeCenterX 
                            multiplier:1.0 
                              constant:0]</pre>
<p>&nbsp;</p>
<p>Using this to place a button on a UIView the could would look like this:<br />
<img alt="NSLayoutConstraint Example" src="http://rutgeri.files.wordpress.com/2013/06/screen-shot-2013-06-07-at-9-58-22-am.png" /></p>
<p>The first thing to notice is the fact that the second constraint could be formulated differently while getting the same result. In the code example I define the horizontal position of the button to lead the left edge of the superview by 50. However, if I changed the first attibute to NSLayoutAttributeLeft it would instead say that the spacing between the left side of the button and the left side of the superview should be 50. This works because it is inside of the superview. However, if you would want to space two buttons, the second option would not work, this would result in a partial overlap of the buttons since the second button would be placed 50 points from the left of the first button. Instead you would have to use the NSLayoutAttributeRight to define the constraint. If you are planning to use AutoLayout in your applications, make sure you understand the different NSLayoutAttributes and how they affect your components.</p>
<p>Another key element is the following line, if you do not set the TranslatesAutoresizingMaskIntoConstraints to NO/FALSE it will generate it&#8217;s own constraints, which will then conflict with yours. So you want to make sure to turn this of for all your components that you define constraints for.</p>
<pre class="wp-code-highlight prettyprint">[button1 setTranslatesAutoresizingMaskIntoConstraints:NO];</pre>
<p>Unfortunately this leaves us with quite a lot of code if we have to place constraints on a set of UIViews. There are two ways to deal with this excess of code. We can create a category for UIViews that adds some simplified functions to deal with most of the constraints that need to be set. The second option is to use the <a title="Visual Format Language" href="https://developer.apple.com/library/mac/documentation/UserExperience/Conceptual/AutolayoutPG/Articles/formatLanguage.html#//apple_ref/doc/uid/TP40010853-CH3-SW1" target="_blank">Visual Format Language</a>(VFL). The latter allows your to use a shorthand notation for your contraints, but more importantly, it allows you to set multiple constraints simultaniously.</p>
<p>To see this in action, lets have a look at a UITextView, if we set it the same way we did with our button we get a black screen, the UITextView will not show up, not even if we set some text. This is because the UITextView does not have have an intrinsicContentSize defined, which means that if you do not tell it what size it should be, it does not know and assumes 0. To fix this we need to set a height and width constraint like in the following example.</p>
<div class="wp-caption alignnone" style="width: 504px"><a href="http://rutgeri.files.wordpress.com/2013/06/textview-layout.png"><img alt="" src="http://rutgeri.files.wordpress.com/2013/06/textview-layout.png" width="494" height="615" /></a><p class="wp-caption-text">UITextView Layout Example</p></div>
<p>If we would write this in VFL it would look like this:</p>
<p><a href="http://rutgeri.files.wordpress.com/2013/06/textview-vfl.png"><img class="alignnone" alt="" src="http://rutgeri.files.wordpress.com/2013/06/textview-vfl.png" width="761" height="288" /></a></p>
<p>In the above example you will notice two things, unlike in the earlier examples here I add the UITextView to it&#8217;s superview before I set the constraints. We have to do this because within the constraint we refer to our superview implicitely instead of explicitely, which requires us to have a superview before setting the constraint. If you do not do this correctly the app will terminate throwing a NSInvalidArgumentException &#8220;Unable to interpret &#8216;|&#8217; character, because the related view doesn&#8217;t have a superview&#8221;.</p>
<p>Secondly we now have a dictionary with the views we want to set constraints for, the VFL uses this to refer to the proper UIView object using the keys.</p>
<p>Most importantly though, we now have a shorter way to set our constraints, and we can set all the horizontal or vertical constraints on one UIView at once!</p>
]]></content:encoded>
			<wfw:commentRss>http://technology.amis.nl/2013/06/07/autolayout/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Understanding Storage, Masterclass by James Morle</title>
		<link>http://technology.amis.nl/2013/06/06/understanding-storage-masterclass-by-james-morle/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=understanding-storage-masterclass-by-james-morle</link>
		<comments>http://technology.amis.nl/2013/06/06/understanding-storage-masterclass-by-james-morle/#comments</comments>
		<pubDate>Thu, 06 Jun 2013 20:15:51 +0000</pubDate>
		<dc:creator>Patrick Roozen</dc:creator>
				<category><![CDATA[AMIS]]></category>
		<category><![CDATA[DBA]]></category>
		<category><![CDATA[IT Architecture]]></category>
		<category><![CDATA[james morle]]></category>
		<category><![CDATA[masterclass]]></category>
		<category><![CDATA[understanding storage masterclass]]></category>

		<guid isPermaLink="false">http://technology.amis.nl/?p=23340</guid>
		<description><![CDATA[Today was the first day of the two day Masterclass &#8220;Understanding Storage&#8221;  by James Morle at AMIS.
After having reserved my participation in this Masterclass on March 12th, the first day has finally arrived. My colleague Marco Gralike already blogged about the contents of this Masterclass  [...]]]></description>
				<content:encoded><![CDATA[<p>Today was the first day of the two day Masterclass &#8220;Understanding Storage&#8221;  by James Morle at AMIS.</p>
<p>After having reserved my participation in this Masterclass on March 12th, the first day has finally arrived. My colleague Marco Gralike already blogged about the contents of this <a title="Understanding Storage" href="http://technology.amis.nl/2013/03/16/amis-masterclasses-two-day-masterclass-with-oracle-ace-director-james-morle/">Masterclass</a> therefore I will not repeat it here. James is well known in the Oracle community, not in the least for his book: Scaling Oracle 8i. That book was recommended to me today by another participant and is available <a title="Scaling Oracle 8i" href="http://www.scaleabilities.co.uk/scalingoracle8i/">here</a>. I must confess I&#8217;ve probably downloaded it years before but have never gotten around to reading it properly.<span id="more-23340"></span> I will make that a priority as I believe now that has been a mistake of mine. The concepts are still valid today as they were then.</p>
<p>Listening to James is very easy to do because he captures your attention with ease. His presentation is a mix of theory, explaining in detail, asking questions to the audience (in order to make us think), and answering our questions. I believe that my understanding of Storage, how it works in detail, how it interacts with the Oracle database, will be much better after also completing day 2. I can hardly wait for tomorrow.</p>
<p>I&#8217;ve got lot&#8217;s of things to check and verify when I&#8217;m back at my &#8220;regular&#8221; customer. Since I&#8217;m, as a member of a lean team, also responsible for the EMC Storage there. That is a benefit of this Masterclass: I shall be able to ask sensible questions to the SAN administrator(s) (But may give the answers myself&#8230;). And I should be able to make more sense of the EMC data that is available to us.</p>
<p>Patrick</p>
]]></content:encoded>
			<wfw:commentRss>http://technology.amis.nl/2013/06/06/understanding-storage-masterclass-by-james-morle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Emulate Cross Service Joins in SOA Suite with Table Functions and Database Adapter</title>
		<link>http://technology.amis.nl/2013/06/05/emulate-cross-service-joins-in-soa-suite-with-table-functions-and-database-adapter/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=emulate-cross-service-joins-in-soa-suite-with-table-functions-and-database-adapter</link>
		<comments>http://technology.amis.nl/2013/06/05/emulate-cross-service-joins-in-soa-suite-with-table-functions-and-database-adapter/#comments</comments>
		<pubDate>Wed, 05 Jun 2013 15:38:13 +0000</pubDate>
		<dc:creator>Lucas Jellema</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[SOA & Oracle Fusion Middleware]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[collect]]></category>
		<category><![CDATA[data consolidation]]></category>
		<category><![CDATA[data management]]></category>
		<category><![CDATA[database adapter]]></category>
		<category><![CDATA[domain]]></category>
		<category><![CDATA[join]]></category>
		<category><![CDATA[nested table]]></category>
		<category><![CDATA[service]]></category>
		<category><![CDATA[soa]]></category>
		<category><![CDATA[soa suite]]></category>
		<category><![CDATA[table function]]></category>

		<guid isPermaLink="false">http://technology.amis.nl/?p=23332</guid>
		<description><![CDATA[It was fairly difficult to come up with a title for this article that sort of covers the content. To me it is quite clear what this is about &#8211; but how to convey that in a title? Let me explain: today in our project we discussed the implementation of a data service. The service operation under  [...]]]></description>
				<content:encoded><![CDATA[<p>It was fairly difficult to come up with a title for this article that sort of covers the content. To me it is quite clear what this is about &#8211; but how to convey that in a title? Let me explain: today in our project we discussed the implementation of a data service. The service operation under scrutiny takes a city as input and returns a list all open orders from customers located in that city. Nothing very special there. The interesting complication lies in the fact that the customers are part of a different domain than the orders. This means &#8211; under our architecture guidelines &#8211; that we cannot create a single SQL query that joins together the customers table with the orders table. A database link to join the tables across databases is out of the question and even if these tables currently reside in the same database &#8211; such a join is not allowed. Different data domains are treated as independent entities and no direct dependencies between the two should be created. Every design has pass the check ‘will it still work if one of the domains involved were to be relocated to the cloud or be replaced by a third party application’.</p>
<p>The architecture is service oriented. Every domain exposes services that provide access to data and business logic. The implementation of these services and the underlying domain is encapsulated. Consumers of the domain services are unaware of the domain internals, therefore they have no dependencies on such internals and will not be affected if the internals change. For as long as the domain adheres to its service contracts, all consumers can continue to function. This even applies if the domain is moved to a different physical location or reimplemented using a COTS (commercial off the shelf) product.</p>
<p>So there we had it: a sound service oriented architecture with fairly strict guidelines and a clear business requirement. The composite service we were tasked with implementing would somehow have to make use of two domain services &#8211; one on the CRM domain and one on the SALES domain &#8211; to find the customers in the location specified and find all open orders for these customers.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image12.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb12.png" width="615" height="437" border="0" /></a></p>
<p>The call to the CustomerService’s findCustomers operation would return a list of customer identifier values. What to do next? Loop over all identifiers and retrieve the orders for the customer identifier &#8211; merging all results returned by all calls to OrderServicer.retrieveOrdersForCustomers? Potentially making dozens or more calls to the OrderService? Or perhaps we could transfer the  list of customer identifiers to the OrderService and let it take care of getting all orders for all the customers in the list. But how can we implement this in an efficient manner? How do we prevent executing the query to fetch the orders as many times as there are customer identifiers?</p>
<p>It turned out to be quite simple to address this challenge. Using the Oracle SQL Table Function and the database adapter we can very easily create a SQL query that joins the orders table with the list of customer identifiers. Only a single query is executed against the SALES database and a single round trip suffices to get all order records. The whole approach is of course not as efficient as doing a straight join across the two tables, but in this service oriented context it is not bad at all.</p>
<p>Let’s take a look at the implementation.</p>
<p><span id="more-23332"></span></p>
<h3>Starting at the end</h3>
<p>The final result will be like this: three SOA Suite composites are used, one for each of the three services from the original design. Two of these are Domain Services; these use a database adapter to retrieve data from their Domain data store &#8211; which happens to be a relational database in both instances.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image13.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb13.png" width="1408" height="706" border="0" /></a></p>
<p>When the CustomerOrderService is invoked to return all Open Orders for Customers located in the specified location, the BPEL process in the CustomerOrderService Composite will first invoke the CustomerService that &#8211; using its database adapter against the CRM database &#8211; will return a list of customer identifiers. Next, the BPEL process will use this list of identifiers as input in its call to the OrderService. This latter service is exposed by another SCA composite that has its own database adapter invoking a PL/SQL package. In the call to this package, the entire list of identifiers is passed in. Inside the package, a SQL query is performed (that joins the customer identifiers list to the ORDERS table); this query returns the Orders (for the specified customers and with the appropriate status). The important message is that only one query is performed against the ORDERS table in the SALES database. And regardless of the number of customers involved &#8211; it will always be a single query.</p>
<p>Even though the service discussed in this article stretches across two data domains and although joins across these domains are not allowed in SQL queries, we still only required two queries (rather than a single query for each customer). In addition: the consumer of the operation is none the wiser about the underlying structure or whereabouts of the data. Whether the composite service enlisted Cloud based resources, a file system or a number of relational data stores: it is completely hidden from view. As it should be. The remainder of this article demonstrates exactly how this was realized.</p>
<h3>Implementation of the CustomerService</h3>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image14.png"><img style="background-image: none; float: right; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb14.png" width="329" height="198" align="right" border="0" /></a>Let’s assume a very simple CRM system. A single database table called CUSTOMERS with just four columns. It is enough to serve the purpose of this article. A number of customer records is created in this table.</p>
<p>The CustomerService is implemented using a SOA Suite Composite Application; note: we could just as well have used the Service Bus in this case.</p>
<p>The composite exposes the service with the agreed upon CustomerService interface (described by a WSDL and associated XSD document). A Mediator component implements that interface and maps it to a database adapter service that has been configured to query from the CUSTOMERS table all those customer records that have the required value in their CITY column.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image15.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb15.png" width="705" height="276" border="0" /></a></p>
<p>The database adapter configuration is fairly straightforward: the adapter performs a query against table CUSTOMERS and retrieves all records with a CITY value equal to the location parameter.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image16.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb16.png" width="931" height="529" border="0" /></a></p>
<p>The Mediator maps the input and output messages specified in the CustomerService contract to the input and output required by the database adapter service based on this configuration.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image17.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb17.png" width="819" height="177" border="0" /></a></p>
<p>After deployment, the CustomerService can easily be tested. Given a location, it will return a list of customer identifiers.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image18.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb18.png" width="1042" height="475" border="0" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>Implementation of the OrderService</h3>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image19.png"><img style="background-image: none; float: right; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb19.png" width="237" height="244" align="right" border="0" /></a>The implementation of the OrderService takes place at two levels. First at the database level &#8211; where a PL/SQL package is created to produce a collection of Order objects based on a collection of Customer identifiers. This package is created, deployed and tested on its own. The second step involves the SOA Suite: a database adapter configuration is created to invoke this PL/SQL package and using a Mediator mapping a pretty service interface to this database adapter the composite is completed, deployed and also tested.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image20.png"><img style="background-image: none; float: left; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb20.png" width="276" height="154" align="left" border="0" /></a>Step one is not SOA Suite specific. The PL/SQL package that returns the collection of Order Records is an example of a encapsulated service &#8211; not your typical web service but instead a PL/SQL based API and implementation which is a service just as well. The package contains a SQL query that retrieves records from the ORDERS table. The records are filtered by CTR_ID (the column that contains the customer identifier). This is done using a join to a Nested Table rather than a WHERE condition. Read on, and the what and how are revealed.</p>
<p>The ORDER details are returned from the package as a nested table of objects &#8211; using the very powerful yet fairly little known database mechanism of objects and table of objects. Using these next SQL statements, the object and the table of object types are created in the database:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image21.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb21.png" width="299" height="242" border="0" /></a></p>
<p>These statements create a type ORDER_TABLE_T &#8211; a collection of ORDER_T objects &#8211; and ORDER_T itself that describes an object with five attributes. Instances of these objects can be created &#8211; in SQL and PL/SQL &#8211; and they can be passed around between for example the database adapter and a PL/SQL package.</p>
<p>The package specification that the database adapter will be created against is defined as follows:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image22.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb22.png" width="309" height="266" border="0" /></a></p>
<p>The function find_orders is invoked with a number_table_t &#8211; defined as CREATE TYPE NUMBER_TABLE_T AS TABLE OF NUMBER &#8211; that contains the identifiers of the customers whose orders should be retrieved. Other search criteria are the status of the orders and an upper and lower boundary for the order amount. The function returns an instance of order_table_t &#8211; which means it returns a collection of order_t objects.</p>
<p>The implementation of the function is fairly straightforward &#8211; if you are familiar with the use of nested table collections, the COLLECT aggregation operator and the TABLE FUNCTION operator in SQL. Note that these features were introduced in Oracle Database 8.0, 10g and 9i respectively. They have been around for a while.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image23.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb23.png" width="870" height="480" border="0" /></a></p>
<p>The most interesting part of the function is highlighted in the red rectangle: table ORDERS is joined with something that is not a real table but that behaves as one. Using the TABLE function on the nested table collection with customer identifiers (p_customers_tbl) the query behaves as if a table with customer identifiers does indeed exist (with a single column whose value we access using the pseudo function column_value) and is joined on the CTR_ID column with the ORDERS table. Every ORDER record that is returned by the query is transformed into an OBJECT_T instance. All these OBJECT_T instances are taken together &#8211; with the COLLECT operator &#8211; and cast to the ORDER_TABLE_T type. An instance of that latter type is what we need &#8211; because it is the return type of the function.</p>
<p>A simple test &#8211; in PL/SQL &#8211; of this function looks like this:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image24.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb24.png" width="539" height="387" border="0" /></a></p>
<p>and the output through the server output in this case:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image25.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb25.png" width="235" height="129" border="0" /></a></p>
<p>With this PL/SQL package in place, the OrderService is quickly created using a database adapter. Note that the database adapter is remarkably good at dealing with Object Types and Nested Table collections.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image26.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb26.png" width="496" height="305" border="0" /></a></p>
<p>The composite is further fleshed out &#8211; based on the predefined WSDL and XSD for the OrderService and using a Mediator to map from that external interface to whatever the database adapter is offering:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image27.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb27.png" width="782" height="238" border="0" /></a></p>
<p>The mapping in the transformation is fairly simple &#8211; because of the very adequate conversion performed by the database adapter from the database types of ORDER_TABLE_T and ORDER_T to their counterpart XSD types:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image28.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb28.png" width="788" height="207" border="0" /></a></p>
<p>After deployment of the composite OrderService, we can test it &#8211; with the same input as the PL/SQL test of the ORDER_SERVICE_IMPL package:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image29.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb29.png" width="788" height="510" border="0" /></a></p>
<p>At this point both the domain services have been created and deployed. We are ready to create the composite CustomerOrderService. Note that the hardest work has been done by now, inside the PL/SQL package.</p>
<p>&nbsp;</p>
<h3>Implementation of the Composite CustomerOrderService</h3>
<p>BPEL’s core strength is orchestrating web service calls. It is the perfect tool in many occasions to create a composite service. The CustomerOrderService is such a composite service &#8211; a service that uses multiple other services for its implementation. This architecture view tells the story of the CustomerOrderService:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image30.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb30.png" width="662" height="270" border="0" /></a></p>
<p>This service invokes the CustomerService (in the CRM Domain) as well as the OrderService (in the SALES domain). BPEL is used to implement the composite service. This overview of the SCA Composite for the CustomerOrderService says it all:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image31.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb31.png" width="662" height="308" border="0" /></a></p>
<p>WebService References are created in the composite for each of the two domain level services that need to be invoked. A BPEL component is added and wired to these two references. The CustomerOrderService is exposed as service and wired to the BPEL component. In go a location and out comes a list of orders:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image32.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb32.png" width="1172" height="525" border="0" /></a></p>
<p>The BPEL process itself is easily described. Step one &#8211; the first scope &#8211; consists of invoking the CustomerService to retrieve a list of customer identifiers for all customers located at the designated location. The second step &#8211; scope number two &#8211; entails calling the OrderService with this list of identifiers in order to retrieve the sought after order details.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image33.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb33.png" width="633" height="502" border="0" /></a></p>
<p>A global BPEL variable is used to store the list of identifiers and carry over this list from the first to the second scope. The second scope contains two Transform activities &#8211; one to map the customer identifiers to the input variable for the OrderService and the second one to map the output from the OrderService call (the order records) to the output variable of the BPEL process.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image34.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb34.png" width="630" height="520" border="0" /></a></p>
<p>Let us do a simple test: find all the open orders for customers located in Zoetermeer:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image35.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb35.png" width="969" height="390" border="0" /></a></p>
<p>The message flow trace makes it clear what happened during the execution of the CustomerOrderService:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image36.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-width: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb36.png" width="583" height="318" border="0" /></a></p>
<p>A BPEL process is instantiated. It invokes the CustomerService &#8211; that in turn makes a single call to a database adapter service (for the query against CUSTOMERS). Next the BPEL process goes on to invoke the OrderService (just a single invocation). This composite too invokes a database adapter service (for the query against the ORDERS table). This is also a single call &#8211; a single round trip from SOA Suite run time to the database.</p>
<p>We have retrieved records based on a join across the domains CRM and SALES &#8211; without actually creating a dependency between the two databases involved &#8211; and without sacrificing [a lot] in terms of elegance, performance and scalability.</p>
<h2>Resources</h2>
<p>Download the JDeveloper 11.1.1.7 (11gR1 PS6) workspace with all the sources discussed in this article: <a href="http://technology.amis.nl/wp-content/uploads/2013/06/CrossServiceJoin.zip">CrossServiceJoin,zip</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://technology.amis.nl/2013/06/05/emulate-cross-service-joins-in-soa-suite-with-table-functions-and-database-adapter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ADF Academy launched- interactive, entertaining and educational</title>
		<link>http://technology.amis.nl/2013/06/03/adf-academy-launched-interactive-entertaining-and-educational/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=adf-academy-launched-interactive-entertaining-and-educational</link>
		<comments>http://technology.amis.nl/2013/06/03/adf-academy-launched-interactive-entertaining-and-educational/#comments</comments>
		<pubDate>Mon, 03 Jun 2013 04:19:31 +0000</pubDate>
		<dc:creator>Lucas Jellema</dc:creator>
				<category><![CDATA[ADF & JHeadstart]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[adf]]></category>
		<category><![CDATA[adf academy]]></category>
		<category><![CDATA[demo]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[training]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[webinar]]></category>

		<guid isPermaLink="false">http://technology.amis.nl/?p=23279</guid>
		<description><![CDATA[Last week I was prompted to take a look at the new Oracle ADF Academy that has just published its first lesson: Developing Applications with ADF Mobile. As you probably already know, there are tons of resources on ADF. Blogs, books, tutorials, Oracle by Example instructions, YouTube movies,  [...]]]></description>
				<content:encoded><![CDATA[<p>Last week I was prompted to take a look at the <a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/academy/Developing%20Applications%20with%20ADF%20Mobile/player.html" target="_blank">new Oracle ADF Academy</a> that has just published its first lesson: Developing Applications with ADF Mobile. As you probably already know, there are tons of resources on ADF. Blogs, books, tutorials, Oracle by Example instructions, YouTube movies, extensive documentations, how-tos, the forums, podcasts and more still. What could this ADF Academy add to the mix, I was wondering?</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb.png" width="621" height="405" border="0" /></a></p>
<p>Here is what Oracle says about it:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image1.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb1.png" width="575" height="180" border="0" /></a></p>
<p><span id="more-23279"></span></p>
<p>I had not read this description prior to watching (or experiencing) the first lesson; but it proved true. I was very pleasantly surprised. The ADF Academy is a multi media <em>experience</em> that uses every trick in the book &#8211; or every option for interaction, illustration, explanation and demonstration I could think of.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image2.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb2.png" width="488" height="306" border="0" /></a></p>
<p>Different voices, music, code samples, cartoons, demonstrations, bits of video.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image3.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb3.png" width="244" height="160" border="0" /></a></p>
<p>I frequently attend webinars &#8211; and they typically very quickly get boring and I have a hard time focusing and staying engaged. The voice drones on, the graphics are power point slides, the story is too high level (or far too detailed). There are many pitfalls for such on-line trainings. I still like my books very much &#8211; as they allow me my own pace and to some extent imagination as well. But of course when reading a book, I need to work through samples to bring things to life.</p>
<p>It seems that ADF Academy has adopted something close to the style of perhaps my favorite range of text books: the Head First [Java|Design Patterns|..] series. The Head First books also use every option in terms of rephrasing and visualizing the concepts under scrutiny. Cartoons are frequently used to clarify and underline the important messages. Here is one of the pages in the lesson on ADF Mobile application Development:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image4.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb4.png" width="717" height="542" border="0" /></a></p>
<p>At first glance, these cartoons may seem a little childish perhaps. But it is my personal experience that they make learning fun. It helps to refocus &#8211; also to break through what otherwise might have been a monotonous experience.</p>
<p>Note that it is not <em>just</em> cartoons. There is live demo:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image5.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb5.png" width="244" height="140" border="0" /></a></p>
<p>and source code:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image6.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb6.png" width="244" height="184" border="0" /></a></p>
<p>overviews of what the next section will teach us:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image7.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb7.png" width="244" height="186" border="0" /></a></p>
<p>architecture overviews:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image8.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb8.png" width="244" height="184" border="0" /></a></p>
<p>step by step code clarification (both through audio and visuals):</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image9.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb9.png" width="244" height="184" border="0" /></a></p>
<p>and self test quizzes:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image10.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb10.png" width="244" height="184" border="0" /></a></p>
<p>An additional bonus in the lesson is the appearance of several key people whose names you may know from forums or blogs &#8211; now suddenly doing bits and pieces of live action explanation. Here is Chris Muir making a contribution from Perth, Australia:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/06/image11.png"><img style="background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/06/image_thumb11.png" width="465" height="346" border="0" /></a></p>
<p>All in all I think that this way of presenting information and teaching me about using special aspects of ADF is a great addition to all existing resources. It is fun to watch, entertaining, has a good structure, explains both the high level overview as well as the fine grained technical details. In any review I like to find fault with whatever I am reviewing, just like a tester is out to uncover bugs. However, I am really happy with the <a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/academy/Developing%20Applications%20with%20ADF%20Mobile/player.html" target="_blank">ADF Academy</a>. I am looking forward to additional lessons. Well done ADF-team!</p>
]]></content:encoded>
			<wfw:commentRss>http://technology.amis.nl/2013/06/03/adf-academy-launched-interactive-entertaining-and-educational/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ADF Mobile : Oracle eCourse available</title>
		<link>http://technology.amis.nl/2013/05/31/adf-mobile-oracle-ecourse-available/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=adf-mobile-oracle-ecourse-available</link>
		<comments>http://technology.amis.nl/2013/05/31/adf-mobile-oracle-ecourse-available/#comments</comments>
		<pubDate>Fri, 31 May 2013 18:37:10 +0000</pubDate>
		<dc:creator>Luc Bors</dc:creator>
				<category><![CDATA[ADF & JHeadstart]]></category>
		<category><![CDATA[AMIS]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[adf]]></category>
		<category><![CDATA[adf mobile]]></category>
		<category><![CDATA[training]]></category>

		<guid isPermaLink="false">http://technology.amis.nl/?p=23247</guid>
		<description><![CDATA[Today Oracle published the first in a series of online eLearning training materials. The ADF Academy presents free and online : Developing Applications with ADF Mobile. The main goal is to deliver technical training material to everybody that needs it. You get an online training, where you can view  [...]]]></description>
				<content:encoded><![CDATA[<p>Today Oracle published the first in a series of online eLearning training materials. The ADF Academy presents free and online : Developing Applications with ADF Mobile. The main goal is to deliver technical training material to everybody that needs it. You get an online training, where you can view audio and video to learn ADF. Whenever you want to you can stop the recordings to try out everything that you learned so far, or perhaps to get a drink.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/05/academy.png"><img class="aligncenter size-medium wp-image-23252" alt="academy" src="http://technology.amis.nl/wp-content/uploads/2013/05/academy-208x300.png" width="208" height="300" /></a></p>
<p>Developing Applications with ADF Mobile <a title="is available here." href="http://download.oracle.com/otn_hosted_doc/jdeveloper/academy/Developing%20Applications%20with%20ADF%20Mobile/player.html" target="_blank">is available here</a>.</p>
<p>Take to opportunity and learn to work with a great framework to develop mobile applications for iOS and Adroid.</p>
<p>Also keep an eye on technology.amis.nl for more ADF Mobile related content.</p>
]]></content:encoded>
			<wfw:commentRss>http://technology.amis.nl/2013/05/31/adf-mobile-oracle-ecourse-available/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ADF: (Automatic) Partial Page Rendering across Taskflows</title>
		<link>http://technology.amis.nl/2013/05/14/adf-automatic-partial-page-rendering-across-taskflows/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=adf-automatic-partial-page-rendering-across-taskflows</link>
		<comments>http://technology.amis.nl/2013/05/14/adf-automatic-partial-page-rendering-across-taskflows/#comments</comments>
		<pubDate>Tue, 14 May 2013 13:45:50 +0000</pubDate>
		<dc:creator>Paco van der Linden</dc:creator>
				<category><![CDATA[ADF & JHeadstart]]></category>
		<category><![CDATA[AMIS]]></category>
		<category><![CDATA[J(2)EE/Java]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[adf]]></category>
		<category><![CDATA[adf 11g]]></category>
		<category><![CDATA[ppr]]></category>

		<guid isPermaLink="false">http://technology.amis.nl/?p=23203</guid>
		<description><![CDATA[One of the great features of ADF is the easy out-of-the-box support for Partial Page Rendering (PPR) using the partialTriggers, autoSubmit&#160;and partialSubmit&#160;properties. And when things get a bit more complex there is a very easy API to do it programmatically. But what if

you don’t know beforehand  [...]]]></description>
				<content:encoded><![CDATA[<p>One of the great features of ADF is the easy out-of-the-box support for Partial Page Rendering (PPR) <a href="http://docs.oracle.com/cd/E28280_01/web.1111/b31973/af_ppr.htm#BABHBJFH" target="_blank">using the <span style="font-family: Courier New, Courier, monospace">partialTriggers</span>, <span style="font-family: Courier New, Courier, monospace">autoSubmit</span>&nbsp;and <span style="font-family: Courier New, Courier, monospace">partialSubmit</span>&nbsp;properties</a>. And when things get a bit more complex there is a very easy <a href="http://docs.oracle.com/cd/E28280_01/web.1111/b31973/af_ppr.htm#BGBIIDBF" target="_blank">API to do it programmatically</a>. But what if</p>
<ul>
<li>you don’t know beforehand what attribute or column will change, or</li>
<li>you don’t want to replicate this “Model logic” in the View layer (e.g. because you want to adhere to the <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" target="_blank">Model-View-Controller pattern</a>), or</li>
<li>components are scattered across Taskflows (in which case you cannot use the declarative support and the programmatic approach is suddenly very hard)?</li>
</ul>
<p>Fortunately, ADF has a solution: <strong>Automatic Partial Page Rendering</strong> (or Auto PPR). If you have used ADF with Business Components, you might have seen or used it already, but it is less obvious that you can also use it with ordinary Beans or Bean DataControls.</p>
<p><span id="more-23203"></span></p>
<p><strong>Using Business Components</strong></p>
<p>With ADF Business Components this is almost too easy. The ADF BC DataControl automatically maintains per Attribute a list of View Components that use/display it. It also keeps track of changes in attributes. The only thing you need to do is tell it that it should use this information for Auto PPR, using one simple property: <span style="font-family: Courier New, Courier, monospace">ChangeEventPolicy</span> in the PageDef. You can set it on an <span style="font-family: Courier New, Courier, monospace">attributeValues</span> binding. In that case only changes from that particular attribute will be propagated automatically, for example:</p>
<p>[xml]<br />
&lt;attributeValues IterBinding=&#8221;EmployeesView1Iterator&#8221; id=&#8221;FullName&#8221; ChangeEventPolicy=&#8221;ppr&#8221;&gt;<br />
  &lt;AttrNames&gt;<br />
    &lt;Item Value=&#8221;FullName&#8221;/&gt;<br />
  &lt;/AttrNames&gt;<br />
&lt;/attributeValues&gt;<br />
[/xml]</p>
<p>Or you can set it on the <span style="font-family: Courier New, Courier, monospace">iterator</span> binding, in which case it is enabled for all attributes of this iterator:</p>
<p>[xml]<br />
&lt;iterator Binds=&#8221;EmployeesView1&#8243; RangeSize=&#8221;25&#8243; DataControl=&#8221;AppModuleDataControl&#8221;<br />
          id=&#8221;EmployeesView1Iterator&#8221; ChangeEventPolicy=&#8221;ppr&#8221;/&gt;<br />
[/xml]</p>
<p><strong>Using ordinary Beans or Bean DataControls</strong></p>
<p>As explained above, ADF Business Components automatically maintains a list of consuming Components and keeps track of changes, but your Bean – being a Plain Old Java Object – obviously does not. Suppose we want to create the following “application”:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/05/image6.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="image" alt="image" src="http://technology.amis.nl/wp-content/uploads/2013/05/image_thumb6.png" width="387" height="337" border="0" /></a></p>
<p>Whenever someone enters a <em>first name</em> or a <em>last name</em>, the <em>full name</em> updates. When the <em>full name</em> updates (whenever someone enters something in any of the name fields) the bottom label also updates to reflect the new <em>full name</em>. This would be very easy using <span style="font-family: Courier New, Courier, monospace">partialTriggers</span> if it weren’t for the fact that the name fields are in a separate Taskflow. This Taskflow is included in a region on the page that contains the “<em>Enter a bio for &lt;FullName&gt;</em>” label.</p>
<p>This example is obviously made up for this blogpost, but situations like this are quite common. It is not hard to imagine that you would want to reuse the logic to enter a person’s name, but also use the person’s full name in other parts of the application. You don’t know (in the context of the “<em>Name details</em>” Taskflow) all the components in other parts of the application that depend on the <em>full name</em>. In fact you don’t <strong>want</strong> to know, because that would rather defeat the purpose of the Taskflow (i.e. reuse and modularization). So the programmatic approach is also not an option.</p>
<p>The basis of the implementation is a DataControl based on the following bean (not yet including the Auto PPR logic):</p>
<p>[java]<br />
public class EmployeeBean {<br />
  private String firstName, lastName, fullName;</p>
<p>  public void setFirstName(String firstName) {<br />
    this.firstName = firstName;<br />
    refreshFullName();<br />
  }</p>
<p>  public String getFirstName() {<br />
    return firstName;<br />
  }</p>
<p>  public void setLastName(String lastName) {<br />
    this.lastName = lastName;<br />
    refreshFullName();<br />
  }</p>
<p>  public String getLastName() {<br />
    return lastName;<br />
  }</p>
<p>  public void setFullName(String fullName) {<br />
    this.fullName = fullName;<br />
  }</p>
<p>  public String getFullName() {<br />
    return fullName;<br />
  }</p>
<p>  private void refreshFullName() {<br />
    String first = firstName == null ? &#8220;&#8221; : firstName;<br />
    String fullName = lastName == null ? first : first + &#8221; &#8221; + lastName;<br />
    setFullName(fullName);<br />
  }<br />
}<br />
[/java]</p>
<p>Now, we need to do two things:</p>
<ol>
<li>Whenever <span style="font-family: Courier New, Courier, monospace">getFullName()</span> gets called we want to remember the consumer (JSF Component) that requested it.</li>
<li>Whenever <span style="font-family: Courier New, Courier, monospace">setFullName(String)</span> gets called we want to do a partial update of all the components that we remembered from step 1.</li>
</ol>
<p>This sounds easy and it also turns out to be easy. We can reuse the part of the ADF framework that does this for ADF BC. Using <a href="http://pastebin.com/5ihAv8GF" target="_blank">a small utility class (AutoPPRSupport.java)</a> I created for this occasion, the only thing we have to do is add a new member to our bean…</p>
<p>[java]<br />
  private final AutoPPRSupport autoPPRSupport = new AutoPPRSupport();<br />
[/java]</p>
<p>… and change the getFullName() en setFullName(String) as follows…</p>
<p>[java]<br />
  public void setFullName(String fullName) {<br />
    this.fullName = fullName;<br />
    autoPPRSupport.notifyConsumers(&#8220;fullName&#8221;, fullName);<br />
  }</p>
<p>  public String getFullName() {<br />
    autoPPRSupport.rememberConsumerForAttribute(&#8220;fullName&#8221;);<br />
    return fullName;<br />
  }<br />
[/java]</p>
<p>… and that’s it! Now, whenever you use the <em>fullName </em>attribute in a JSF Component, it will automatically update when needed. <a href="https://dl.dropboxusercontent.com/u/35505502/BeanAutoPPR.zip" target="_blank">Download the example.</a></p>
<p>In this particular case we don’t have any rows, so we don’t have to tell the framework which specific row was updated. I leave it as an exercise for the reader to work that one out (hint: using primary keys).</p>
<p><em>(This post also appeared on my personal blog: </em><a href="http://www.adfplus.com"><em>http://www.adfplus.com</em></a><em>.)</em></p>
]]></content:encoded>
			<wfw:commentRss>http://technology.amis.nl/2013/05/14/adf-automatic-partial-page-rendering-across-taskflows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ADF client-side architecture &#8211; Select All</title>
		<link>http://technology.amis.nl/2013/05/07/adf-client-side-architecture-select-all/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=adf-client-side-architecture-select-all</link>
		<comments>http://technology.amis.nl/2013/05/07/adf-client-side-architecture-select-all/#comments</comments>
		<pubDate>Tue, 07 May 2013 12:36:36 +0000</pubDate>
		<dc:creator>Diana Veerman</dc:creator>
				<category><![CDATA[ADF & JHeadstart]]></category>
		<category><![CDATA[AMIS]]></category>
		<category><![CDATA[adf]]></category>
		<category><![CDATA[adf 11g]]></category>
		<category><![CDATA[client side]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://technology.amis.nl/?p=23112</guid>
		<description><![CDATA[A little while ago I got a very nice challenge: play around with the ADF client-side framework.
The customer had a table where users could multi-select via an extra column with checkboxes. Header of that column also contained a checkbox to select or deselect everything at once. For example:

It was  [...]]]></description>
				<content:encoded><![CDATA[<p>A little while ago I got a very nice challenge: play around with the ADF client-side framework.</p>
<p>The customer had a table where users could multi-select via an extra column with checkboxes. Header of that column also contained a checkbox to select or deselect everything at once. For example:<br />
<a href="http://technology.amis.nl/wp-content/uploads/2013/05/screen00036.jpg"><img src="http://technology.amis.nl/wp-content/uploads/2013/05/screen00036.jpg" alt="screen00036" width="250" height="189" class="alignnone size-full wp-image-23176" /></a></p>
<p>It was implemented using autoSubmit and partialTriggers. Due to the roundtrip to the server the response time was low when having a lot of rows. To speed it up, I was asked to look if (de)selecting all rows could be done on the client.</p>
<p>Never having worked with that part of ADF yet, I started searching and quickly found the Oracle documentation, but actual examples to clarify some topics.. hmmm not so much.<br />
The use case is quite specific but I thought it would still be nice to blog about it to be at least an example of some of the client-side functionality for other people in need. <span id="more-23112"></span></p>
<h3>The column</h3>
<p>Let&#8217;s start with the column:<br />
[xml highlight="4,5,6,9"]<br />
&lt;af:table var=&#8221;row&#8221; id=&#8221;tab&#8221; ..&gt;<br />
  &lt;af:column id=&#8221;checkboxCol&#8221; width=&#8221;25&#8243; align=&#8221;center&#8221; displayIndex=&#8221;0&#8243;&gt;<br />
    &lt;f:facet name=&#8221;header&#8221;&gt;<br />
	&lt;af:selectBooleanCheckbox id=&#8221;checkboxHeader&#8221; value=&#8221;#{bindings.selectEmployeeValue.inputValue}&#8221;&gt;<br />
	  &lt;af:clientListener method=&#8221;selectRows&#8221; type=&#8221;click&#8221;/&gt;<br />
	  &lt;af:clientAttribute name=&#8221;tableLocator&#8221; value=&#8221;::tab&#8221;/&gt;<br />
	  &lt;af:clientAttribute name=&#8221;checkboxLocator&#8221; value=&#8221;:checkbox&#8221;/&gt;<br />
	&lt;/af:selectBooleanCheckbox&gt;<br />
    &lt;/f:facet&gt;<br />
    &lt;af:selectBooleanCheckbox id=&#8221;checkbox&#8221; value=&#8221;#{row.selected}&#8221; clientComponent=&#8221;true&#8221;/&gt;<br />
  &lt;/af:column&gt;<br />
  .<br />
  .<br />
&lt;/af:table&gt;<br />
[/xml]</p>
<p>When the user clicks on the checkbox in the header some javascript code will have to loop through the rows to change the checkboxes of each row.</p>
<p>For this I add a client listener to the header checkbox which will trigger on a click and calls some javascript method which in my case I called &#8220;selectRows&#8221;.<br />
To make the javascript method generic I add the table and checkbox identifiers as attributes of the checkbox.<br />
As identifiers I use the locators of the table and row checkboxes relative to the header checkbox; when we look at the javascript it will become clear why.<br />
Last but not least, all row checkboxes get a clientComponent=&#8221;true&#8221; to make sure the client framework can access it.</p>
<p>The ADF client-side architecture wraps around the DOM model and can create javascript objects for faces components.<br />
Javascript objects are created in multiple cases, among others when a component has a clientListener or the property clientComponent=&#8221;true&#8221;.<br />
When looking for API information you can easily guess which API you need to search for. When you have an exposed RichSelectBooleanCheckbox component its javascript equivalent will be an AdfRichSelectBooleanCheckbox.</p>
<h3>The JavaScript</h3>
<p>Defining the client listener is comparable to other server listeners like an action listener.<br />
When you add i.e. an action listener you will need an listener method with an ActionEvent parameter.<br />
A client listener needs a javascript method with an event parameter as well:<br />
[javascript]<br />
  function selectRows(event) { </p>
<p>    /* TODO<br />
       retrieve the header checkbox from the event<br />
       retrieve attributes<br />
	   find the table<br />
       for each row, find the checkbox to set value of<br />
	   while(..){<br />
		  ..<br />
	   }<br />
	*/<br />
  }<br />
[/javascript]</p>
<p>The clientListener is added to the header checkbox making this checkbox the source of the event.<br />
Via the event we can retrieve this AdfRichSelectBooleanCheckbox:<br />
[javascript]<br />
  function selectRows(event) {</p>
<p>    var checkbox=event.getSource(); </p>
<p>    /* TODO<br />
       retrieve attributes<br />
	   find the table<br />
       for each row, find the checkbox to set value of<br />
	   while(..){<br />
		  ..<br />
	   }<br />
	*/<br />
  }<br />
[/javascript]</p>
<p>Once we have our checkbox object we can retrieve its attributes:<br />
[javascript]<br />
  function selectRows(event) {</p>
<p>    var checkbox=event.getSource(); </p>
<p>    var checkboxLocator=checkbox.getProperty(&#8220;checkboxLocator&#8221;);<br />
    var tableLocator=checkbox.getProperty(&#8220;tableLocator&#8221;);</p>
<p>    /* TODO<br />
	   find the table<br />
       for each row, find the checkbox to set value of<br />
	   while(..){<br />
		  ..<br />
	   }<br />
	*/<br />
  }<br />
[/javascript]</p>
<p>The similarities in the client-side architecture are again convenient. The javascript objects have a findComponent method to search from a relative path. The root has a findComponentByAbsoluteId method to search for an object starting from the root. </p>
<p>The tableListener attribute contains the relative path to the table, reasoning from position of the header checkbox. This way we can do a findComponent on the header checkbox to easily get the AdfRichTable object:<br />
[javascript]<br />
  function selectRows(event) {</p>
<p>    var checkbox=event.getSource(); </p>
<p>    var checkboxLocator=checkbox.getProperty(&#8220;checkboxLocator&#8221;);<br />
    var tableLocator=checkbox.getProperty(&#8220;tableLocator&#8221;);</p>
<p>    var table=checkbox.findComponent(tableLocator);</p>
<p>    /* TODO<br />
       for each row, find the checkbox to set value of<br />
	   while(..){<br />
		  ..<br />
	   }<br />
	*/<br />
  }<br />
[/javascript]</p>
<p>So far so good, and nothing that can&#8217;t already be found when googling. But trying to reach the checkboxes of the rows was tricky.<br />
To figure it out I started by looking at the HTML source of the ADF table with the checkbox of the first row:<br />
[xml]<br />
&lt;td style=&#8221;width:25px&#8221; align=&#8221;center&#8221; nowrap=&#8221;" class=&#8221;xxv&#8221;&gt;<br />
  &lt;span id=&#8221;tab:0:checkbox&#8221; class=&#8221;x1v&#8221;&gt;<br />
    &lt;span class=&#8221;x2e&#8221;&gt;<br />
      &lt;span class=&#8221;xgx&#8221;&gt;<br />
         &lt;input id=&#8221;tab:0:checkbox::content&#8221; &#8230;&gt;<br />
      &lt;/span&gt;<br />
    &lt;/span&gt;<br />
  &lt;/span&gt;<br />
&lt;/td&gt;<br />
[/xml]</p>
<p>The ID in the span made me do a couple of first attempts with the findComponent of the header checkbox like<br />
[javascript]checkbox.findComponent(&#8220;::tab["+rowNumber+"]:checkbox&#8221;);[/javascript]</p>
<p>Though this works the first time you open the page, it can break in certain situations.<br />
Problem is that the first row not always gets 0 as a stamp etc. When you for instance have a master-form detail-table layout and navigate to the second master row, your detail row stamp continues to count from the last stamp of the first master row.<br />
But also actions like fetching and refreshing changes the stamps.</p>
<p>After some more searching I found out that finding components by locator should solve the stamp issue.<br />
This allows me to use [0] to address the first row and ADF will look up to which actual stamp this translates at that moment.<br />
It resulted in some next attempts like<br />
[javascript]checkbox.findComponentByLocator(&#8220;::tab["+rowNumber+"]:checkbox&#8221;);[/javascript]</p>
<p>It turned out the table part of the expression was not correct yet.<br />
Some more digging in the APIs to see how I could figure out the locator of the table made me stumble upon AdfUIComponent.getAbsoluteLocator() and a note in AdfUIComponent.findComponentByLocator that there was a method called AdfPage.findComponentByAbsoluteLocator().</p>
<p>Tying those last knots together finally gave a successful result:<br />
[javascript]<br />
  function selectRows(event) {</p>
<p>    var checkbox=event.getSource(); </p>
<p>    var checkboxLocator=checkbox.getProperty(&#8220;checkboxLocator&#8221;);<br />
    var tableLocator=checkbox.getProperty(&#8220;tableLocator&#8221;);</p>
<p>    var table=checkbox.findComponent(tableLocator);</p>
<p>    var nbRows=parseInt(table.getRows());<br />
    var tableAbsLocator=table.getAbsoluteLocator();</p>
<p>    while(nbRows&#8211;){<br />
      var rowCheckbox=AdfPage.PAGE.findComponentByAbsoluteLocator(tableAbsLocator+&#8221;["+nbRows+"]&#8220;+checkboxLocator);<br />
      if(checkbox.getValue()!=rowCheckbox.getValue()){<br />
        rowCheckbox.setValue(checkbox.getValue());<br />
      }<br />
    }<br />
  }<br />
[/javascript]</p>
<p>I have created a quick little project for this.<br />
I immediately admit it is quite ugly as I put the boolean for the checkboxes in my model, but it is just to show the client side selection.</p>
<h3>Note</h3>
<p>This solution only checks or unchecks all <em>fetched </em> rows. As non fetched rows are not in the HTML tree yet it is not possible to check them.<br />
In my use case the query results were maxed to a certain amount which was also used as fetch size to solve this issue.</p>
<h2>Resources</h2>
<p>Oracle white paper &#8211; <a href="http://www.oracle.com/technetwork/developer-tools/jdev/1-2011-javascript-302460.pdf" target="_blank">ADF Design Fundamentals Using JavaScript in ADF Faces Rich Client Application</a></p>
<p>Oracle Web User Interface Developer&#8217;s Guide (11.1.1.5) &#8211; <a href="http://docs.oracle.com/cd/E25054_01/web.1111/b31973/af_arch.htm#ADFUI10021" target="_blank">H3 Using ADF Faces Architecture</a></p>
<p>Oracle Web User Interface Developer&#8217;s Guide (11.1.1.5) &#8211; <a href="http://docs.oracle.com/cd/E25054_01/web.1111/b31973/af_event.htm#DAFEBFEE" target="_blank">H5 Handling Events</a></p>
<p>Oracle JavaScript API Reference (11.1.1) - <a href="http://docs.oracle.com/cd/E21043_01/apirefs.1111/e12046/overview-summary.html" target="_blank">http://docs.oracle.com/cd/E21043_01/apirefs.1111/e12046/overview-summary.html</a></p>
<p>Little example project - <a href="http://technology.amis.nl/wp-content/uploads/2013/05/ClientSideMultiSelect.zip">ClientSideMultiSelect.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://technology.amis.nl/2013/05/07/adf-client-side-architecture-select-all/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iOS App Security &#8211; Backgrounding screenshot</title>
		<link>http://technology.amis.nl/2013/05/03/ios-app-security-backgrounding-screenshot/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ios-app-security-backgrounding-screenshot</link>
		<comments>http://technology.amis.nl/2013/05/03/ios-app-security-backgrounding-screenshot/#comments</comments>
		<pubDate>Fri, 03 May 2013 09:56:49 +0000</pubDate>
		<dc:creator>Rutger van Iperen</dc:creator>
				<category><![CDATA[AMIS]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Backgrounding]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://technology.amis.nl/?p=23105</guid>
		<description><![CDATA[Every time security of apps comes up in any conversation it turns out a lot of people are unaware of this being an issue at all. Simple things like the screenshot iOS takes every time your app gets backgrounded are not the common knowledge I expected it to be by now. In this blog post I wanted to  [...]]]></description>
				<content:encoded><![CDATA[<p>Every time security of apps comes up in any conversation it turns out a lot of people are unaware of this being an issue at all. Simple things like the screenshot iOS takes every time your app gets backgrounded are not the common knowledge I expected it to be by now. In this blog post I wanted to share a few things I learned during a course by <a title="Ken van Wyk - linkedin" href="www.linkedin.com/in/kenvanwyk" target="_blank">Ken van Wyk</a>.</p>
<p>First of all, a must have is Macroplants iExporer. This will let you browse any connected iDevice, including some of the data that gets stored within the apps on the device. Using this tool to have a look at the apps your have built will show you what data is easily accessible for anyone who can hookup the device to their computer. (Spoiler: Even locked and password protected devices can be browsed through iExplorer). Download it <a title="iExplorer" href="http://www.macroplant.com/iexplorer/" target="_blank">here</a> and use it to your advantage.</p>
<p>A lot of these security &#8216;issues&#8217; have everything to do with knowing the platform you are building for. Take for example the backgrounding issue mentioned earlier. As it turns out, iOS will take a screenshot of your app every time it is sent to the background. This screenshot is later used to make your iPhone look a bit quicker when you open your app again, while the app is loaded, iOS will show the screenshot that was taken earlier. If you ever had an app taking a moment before responding again, you were probably pushing buttons on a screenshot. The issue here is that any private data that is on the screen will be stored when the screenshot is taken, these are easily found using iExplorer (or any other application with the same kind of access).</p>
<p>&nbsp;</p>
<div class="wp-caption alignnone" style="width: 742px"><img alt="iExplorer - screenshot location" src="http://rutgeri.files.wordpress.com/2013/05/screen-shot-2013-05-03-at-11-02-02-am.png" width="732" height="592" /><p class="wp-caption-text">iExplorer &#8211; Screenshot Location</p></div>
<p>&nbsp;</p>
<p>Luckily for us, this is fairly easy to anticipate and damage can be prevented with only a few lines of code. In your app delegate you can find the following functions:</p>
<div class="wp-caption alignnone" style="width: 927px"><img alt="" src="http://rutgeri.files.wordpress.com/2013/05/appdelegatefunctions2.png?w=917" width="917" height="138" /><p class="wp-caption-text">AppDelegate Functions to control backgrounding</p></div>
<p>Using  &#8211; (void)applicationDidEnterBackground:(UIApplication *)application  we can ensure to hide any sensitive data from being stored in the screenshot. The most common ways to do this are to show your Default.png image on top of anything else. This way any screenshot will just be a copy of your startup/loading screen, and as an added bonus, when someone starts the app agian they will see a familiar screen.</p>
<div class="wp-caption alignnone" style="width: 887px"><img alt="" src="http://rutgeri.files.wordpress.com/2013/05/appdelegate_functionsdefinite.png?w=877" width="877" height="224" /><p class="wp-caption-text">AppDelegate Functions &#8211; Solution</p></div>
<p>Another way of doing things is to send a notification using NSNotificationCenter. You can then just add an observer for every view where you might want to hide some data. In the specific view you can decide to just hide certain fields or the whole screen.</p>
<p>This example as well as many others is also found in iGoat, an application that will help you to learn a bit more about iOS application security leaks and how to prevent them. I can recommend everyone to check out and download iGoat <a title="iGoat Project" href="https://www.owasp.org/index.php/OWASP_iGoat_Project" target="_blank">here</a>.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://technology.amis.nl/2013/05/03/ios-app-security-backgrounding-screenshot/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ADF DVT Speed Date: Meeting the Pie Graph</title>
		<link>http://technology.amis.nl/2013/05/02/adf-dvt-speed-date-meeting-the-pie-grap/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=adf-dvt-speed-date-meeting-the-pie-grap</link>
		<comments>http://technology.amis.nl/2013/05/02/adf-dvt-speed-date-meeting-the-pie-grap/#comments</comments>
		<pubDate>Thu, 02 May 2013 11:25:10 +0000</pubDate>
		<dc:creator>Diana Veerman</dc:creator>
				<category><![CDATA[AMIS]]></category>

		<guid isPermaLink="false">http://technology.amis.nl/?p=23068</guid>
		<description><![CDATA[Recently the ADF Special Interest Group at AMIS organized an ADF DVT Speed Date. During this speed date, six ADF specialists from our team presented their favorite Data Visualization Component from the DVT library.
In a series of blog posts we share the information with a broader audience.
In this  [...]]]></description>
				<content:encoded><![CDATA[<p>Recently the ADF Special Interest Group at AMIS organized an ADF DVT Speed Date. During this speed date, six ADF specialists from our team presented their favorite Data Visualization Component from the DVT library.<br />
In a series of blog posts we share the information with a broader audience.<br />
In this post you get introduced to Pie Graphs.</p>
<h2>ADF DVT Pie Graph &#8211; Introduction</h2>
<p>The pie chart is one of the most widely used statistical chart for simple representation of the division of data amongst different groups.<br />
It is a simple effective way to see in an instant for example the ratio between country populations when looking at them as portions of the total population.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/05/EoRMJ.png"><img class="alignnone  wp-image-23069" alt="EoRMJ" src="http://technology.amis.nl/wp-content/uploads/2013/05/EoRMJ-1024x564.png" width="573" height="316" /></a></p>
<p>ADF DVT provides smooth looking configurable Pie Graph components in slightly different flavours:<br />
- the pie, a single pie view. For example one pie for the population per country<br />
- the multi pie, a view with mutliple pies. For example per continent a pie with the population per country of that continent<br />
- the pie-bar, For example a pie with the population per continent, with zoom on population per country of that continent<br />
- ring graph<br />
- ring-bar graph</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-11-23.01.jpg"><img class="alignnone  wp-image-23070" alt="ScreenHunter_19 Feb. 11 23.01" src="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-11-23.01.jpg" width="624" height="457" /></a></p>
<p><em>For this blog I will leave out the ring flavours, as they are quite similar.</em></p>
<p>&nbsp;</p>
<p>These ADF components can either be based on some simpel tabular data (via a bean for example) or they can be data bound.<br />
In the latter case, just like other components, you can drag a group from the data control on to your page and choose &#8220;graph&#8221; for the context menu.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-11-23.00.jpg"><img class="alignnone size-full wp-image-23072" alt="ScreenHunter_19 Feb. 11 23.00" src="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-11-23.00.jpg" width="750" height="398" /></a></p>
<p>Dragging a pie graph on the page will result in a couple of things.</p>
<p>1. In design view we see the following:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-11-23.05.jpg"><img class="alignnone  wp-image-23071" alt="ScreenHunter_19 Feb. 11 23.05" src="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-11-23.05.jpg" width="469" height="300" /></a></p>
<p>This is just a dummy pie and is only usefull for when you are configuring titles etc.</p>
<p>2. Then we have the source view, which is quite readable and gives us a hint of how the graph is build and what we could change:<br />
<a href="http://technology.amis.nl/wp-content/uploads/2013/05/screen00069.jpg"><img class="alignnone  wp-image-23092" alt="screen00069" src="http://technology.amis.nl/wp-content/uploads/2013/05/screen00069.jpg" width="494" height="370" /></a><br />
We see the graph itself also contains of subelements, like seriesSet. These can also be clearly seen in the structure pane:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-11-23.57.jpg"><img alt="ScreenHunter_19 Feb. 11 23.57" src="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-11-23.57.jpg" width="192" height="153" /></a></p>
<p>&nbsp;</p>
<p>3. and PageDef:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/05/screen00070.jpg"><img class="alignnone  wp-image-23093" alt="screen00070" src="http://technology.amis.nl/wp-content/uploads/2013/05/screen00070.jpg" width="517" height="376" /></a></p>
<p>Here we can see series and groups. This structure is used for more than just the PIE graph component. In case of the pie graph series are the slices and groups are the grouping data.</p>
<p>So in this example we have a pie with the profit per country.</p>
<h2>ADF DVT Pie Graph &#8211; Properties</h2>
<p>Looking at the properties there are a lot of properties that you are already familiar with from other components, like id, rendered and value property, inlineStyle, styleClass, partialSubmit, bindings changeListeners etc.</p>
<p>Lets focus on the new properties for graphs:</p>
<p><img class="alignnone  wp-image-23076" style="font-size: 0.8em;line-height: normal" alt="Picture1" src="http://technology.amis.nl/wp-content/uploads/2013/05/Picture1.jpg" width="369" height="755" /></p>
<p>We see properties like &#8220;3D effect&#8221; to change a flat pie into the 3D pie shown in the design view screenshot above,properties for animation, titles of different parts of the graph, click listeners, image format (HTML5, Flash, PNG). Each of the subelements of a graph (select via source or structure pane is easiest) also holds properties.</p>
<p>For example, a sliceLabel can be given a numberFormat, resulting in the following:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/05/screen00071.jpg"><img class="alignnone size-full wp-image-23095" alt="DvtPieGraphNumberFormat" src="http://technology.amis.nl/wp-content/uploads/2013/05/screen00071.jpg" width="441" height="127" /></a></p>
<p>Pies can be approached as a table, where a slice then must be looked at as a row. With clickListener and partialTrigger properties we can even create a master-detail with graphs:</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-11-23.29.jpg"><img class="alignnone  wp-image-23077" alt="ScreenHunter_19 Feb. 11 23.29" src="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-11-23.29.jpg" width="638" height="354" /></a></p>
<h2>ADF DVT Pie Graph &#8211; Example</h2>
<p>In this example we are going to play around with different pie graph flavours, properties and create a master-detail.</p>
<p>First please download the this zip, containing a base workspace and some ddl files to set up the DB: <a href="http://technology.amis.nl/wp-content/uploads/2013/05/AdfSpeedDate_PieGraph.zip">AdfSpeedDate_PieGraph</a> (JDev 11.1.1.6)</p>
<h3>Database</h3>
<p>Open workspace DvtPieGraph.jws. Check the settings of the database connection within the application and correct if needed to point to the database for the hand-on session.<br />
Run the install.sql against the database connection.</p>
<p><span style="font-size: 20px;letter-spacing: -0.02em;line-height: normal">Model Layer</span></p>
<p>Workspace DvtPieGraph.jws contains of two projects, Model and ViewController. Model holds an empty Application module and ViewController an empty page to put the DVT components on.</p>
<p>First step we need to take is filling the data control with usefull information. We want to create a page with profit information per country and per restaurant.</p>
<ol start="1">
<li>Create a custom ViewObject CountryFinancesVO.</li>
</ol>
<p>The View object needs to contain the revenue and cost information aggregated per country:</p>
<pre class="wp-code-highlight prettyprint">SELECT countries.id   country_id
,      countries.name country_name
,      SUM(revenue)   country_revenue
,      SUM(costs)     country_costs
FROM   dve_countries    countries
,      dve_restaurants  restaurants
,      dve_revenue      revenue
WHERE  countries.id   = restaurants.country_id
AND    restaurants.id = revenue.restaurant_id
GROUP BY countries.id
       , countries.name</pre>
<p>While creating, don’t add the view Object to the Application Module yet.</p>
<ol start="2">
<li>Add a transient NUMBER attribute to the view object that calculates the countryProfit (revenue-costs).</li>
<li>Create a view object RestaurantFinancesVO, to represent the revenue and cost information per restaurant:</li>
</ol>
<pre class="wp-code-highlight prettyprint">SELECT restaurants.id           restaurant_id
,      restaurants.country_id   country_id
,      restaurants.name         restaurant_name
,      SUM(revenue)             restaurant_revenue
,      SUM(costs)               restaurant_costs
FROM   dve_restaurants  restaurants
,      dve_revenue      revenue
WHERE  restaurants.id = revenue.restaurant_id
GROUP BY restaurants.id
       , restaurants.name
       , restaurants.country_id</pre>
<p>&nbsp;</p>
<ol start="4">
<li>Add a transient NUMBER attribute to the view object that calculates the restaurantProfit.</li>
<li>Create a View link between the two VOs, from Countries to Restaurants, to represent the Master-Detail relationship between them.</li>
</ol>
<p>When creating, add this Link to the Application Module.</p>
<ol start="6">
<li>Open the data model of the Application Module and give the created Master-Detail better names, for example CountryFinances and RestaurantFinancesPerCountry.</li>
</ol>
<p>We are now ready to start with our first graph!</p>
<h3>Let’s make some pies</h3>
<h4>Simple Pie: Profit per Country</h4>
<p>In this exercise we are going to make a pie graph showing the profit per country.</p>
<ol start="1">
<li>Start by opening the .jsff file already available in the ViewController project.</li>
</ol>
<ol start="2">
<li>Open the data control and select the CountryFinances group. Drag this group on the page. This will open the option context menu. Choose “Graph…”</li>
</ol>
<ol start="3">
<li>A Component gallery will open with all kinds of graphs to choose from. Go to the Pie subgallery and choose a single pie and the second quick start layout.</li>
</ol>
<ol start="4">
<li>The next dialog will open to configure the graph. We would like to make a graph on the country profit and see which country is responsible for how much percent of the total profit. See if you can find out which attribute needs to be defined where. Please check the checkbox “Set current row for master-detail”. This option will be for the next exercise. Press OK to place the component on the page.</li>
</ol>
<p>Take a quick look at the source of the page and at the pagedef to see what is generated for this component.</p>
<p>&nbsp;</p>
<ol start="5">
<li>Right-click on the pie. A context menu should open with all kinds of placeholders which are either checked or not. We chose a start layout with a bit too much fluff, make sure the footnote and subtitle are not rendered no more.</li>
</ol>
<ol start="6">
<li>Adjust the title to “Profit per Country” and Legend title to “Country Legend”. Click on parts of the component and look at the property inspector. How does the component look in the structure pane?<span style="line-height: 18px;font-size: 0.8em"> </span></li>
</ol>
<ol start="7">
<li>Go to the properties of the whole graph. Walk a bit through the properties and adjust the graph to a 3d view.</li>
</ol>
<p>Run the page to see the pie.</p>
<ol start="8">
<li>Hoover over the slices and see how the info about profit is shown. Notice how the amount is scaled to for example 60K? This is a setting that can be altered. You can even add your own number format. Try to format it such that the amount shows a currency sign.<span style="line-height: 18px;font-size: 0.8em"> </span></li>
</ol>
<p>Re-run your page to see if it worked!</p>
<h4>Master-Detail Pie: Profit per Restaurant of a Country</h4>
<p>In the first exercise we had checked the option &#8220;Set current row for master-detail&#8221; on the CountryProfit graph. Time to find out what this option does.</p>
<ol start="1">
<li>Go to the property inspector of the graph and find the clickListener to see a value filled in.</li>
</ol>
<p>The option will prepare the first graph act like a master just like in a master-detail screen with tables. Only difference is that instead of master rows we now have master slices.</p>
<ol start="2">
<li>In the model we already prepared for a master-detail, Country-Restaurant, so let’s try to make a detail graph showing the profit sliced per restaurant. Place a horizontal group layout around the first graph.</li>
</ol>
<ol start="3">
<li>In the Data Control panel, drag the group below CountryFinances, RestaurantFinancesPerCountry, on the page next to the Country graph. Choose again a pie graph and try a different start layout just because we can.<span style="line-height: 18px;font-size: 0.8em"> </span></li>
</ol>
<ol start="4">
<li>Clean the component up a little by giving it the title “Profit per Restaurant” and try to figure out how to make sure the subtitle shows “in ” plus the country name of the current selected slice of the Country graph.<span style="line-height: 18px;font-size: 0.8em"> </span></li>
</ol>
<ol start="5">
<li>We already saw the parent is prepared to listen to a click event, but if you run the page you will see the child is not refreshed when the parent is clicked. Make sure the restaurant graph refreshes whenever a slice of the parent is clicked.<span style="line-height: 18px;font-size: 0.8em"> </span></li>
</ol>
<p>Run the page and click to see a nice master-detail page with pies.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-11-23.30.jpg"><img class="alignnone  wp-image-23081" alt="ScreenHunter_19 Feb. 11 23.30" src="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-11-23.30.jpg" width="808" height="434" /></a></p>
<h4>Multi-pie: Costs and Revenue per Restaurant</h4>
<p>One pie at the time should be piece of cake by now. Time to try the multi-pie. Make sure there is another horizontal group layout under the first one.</p>
<ol start="1">
<li>Drag RestaurantFinancesPerCountry on the page in this new group layout but this time choose Multiple Pie. Choose a start layout you like and hit OK.</li>
</ol>
<ol start="2">
<li>So far we looked at profit, but we would like to see a breakdown in costs and revenue. Try to figure out how to make the component show one pie for the restaurant <i>costs</i> showing for which percentage of the costs each restaurant is responsible and one similar pie for the <i>revenue</i>. Two pies Costs and Revenue, showing Restaurant slices..</li>
</ol>
<ol start="3">
<li>It should look like this:</li>
</ol>
<p><a style="line-height: 19px;font-size: 0.8em" href="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-11-23.36.jpg"><img class="alignnone size-full wp-image-23080" alt="ScreenHunter_19 Feb. 11 23.36" src="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-11-23.36.jpg" width="648" height="596" /></a></p>
<ol start="4">
<li>Make sure the graph refreshes when there is a parent slice clicked and run the page to play around with your first multi-pie graph.</li>
</ol>
<h4>Colored pies: cost/revenue pies</h4>
<p>One last time: drag RestaurantFinancesPerCountry at the right of your multi-pie, and choose again a multi-pie. This time let’s see if you are also able to make a pie per restaurant showing the ratio between costs and revenue. So restaurant pies with a cost slice and revenue slice..</p>
<ol start="1">
<li>If you run the page you will see pies being half blue half red. You have to really look at the legend or slice label to see which of the slices are the costs and which are the revenue.</li>
</ol>
<p>I think it would be clearer for the customer if the costs slice would be red and the revenue would be green. Select the graph and take a look at the structure pane.</p>
<ol start="2">
<li>If the pieGraph does not show a seriesSet yet, stand on the graph and choose ‘insert inside dvt:pieGraph..’ and select dvt:seriesSet.</li>
</ol>
<p>Series in ADF represent slices. A seriesSet allows you to set properties for all slices. In our case we want to set two times a property for a specific slice though, so we need a dvt:series within the dvt:seriesSet. Make sure the dvt:seriesSet contains two dvt:series.</p>
<ol start="3">
<li>Select a dvt:series and look at the property inspector. Find the property color and click on the arrow icon at the end to edit. A color picker will show to pick a color from. `</li>
</ol>
<p>Set the colors and run the page.</p>
<p><a href="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-12-00.01.jpg"><img class="alignnone size-full wp-image-23083" alt="ScreenHunter_19 Feb. 12 00.01" src="http://technology.amis.nl/wp-content/uploads/2013/05/ScreenHunter_19-Feb.-12-00.01.jpg" width="790" height="715" /></a></p>
<h2>ADF DVT Pie Graph &#8211; Resources</h2>
<p>Download the JDeveloper 11gR1 11.1.1.6 Start Application - <a href="http://technology.amis.nl/wp-content/uploads/2013/05/AdfSpeedDate_PieGraph.zip">DvtPieGraph.zip</a> and complete application  - <a href="http://technology.amis.nl/wp-content/uploads/2013/05/DvtPieGraph_complete.zip"> DvtPieGraph_complete.zip</a></p>
<p>Oracle documentation of graphs - <a href="http://docs.oracle.com/cd/E25178_01/web.1111/b31973/dv_graph.htm#ADFUI459">http://docs.oracle.com/cd/E25178_01/web.1111/b31973/dv_graph.htm#ADFUI459</a></p>
<p>Oracle Rich Client Live Demo - <a href="http://jdevadf.oracle.com/adf-richclient-demo/faces/feature/">http://jdevadf.oracle.com/adf-richclient-demo/faces/feature</a></p>
]]></content:encoded>
			<wfw:commentRss>http://technology.amis.nl/2013/05/02/adf-dvt-speed-date-meeting-the-pie-grap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
