tag:blogger.com,1999:blog-31400737809079920782024-03-13T16:18:11.144+01:00Oracle ADF - Leaving Competition In The DustTechnology blogJernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.comBlogger14125tag:blogger.com,1999:blog-3140073780907992078.post-86883974834830007582012-05-28T13:09:00.000+01:002012-05-28T13:21:24.421+01:00How to propagate checkbox value in a tree table<div class="separator" style="clear: both; text-align: justify;">
In this blog entry, I'm sharing a possible solution for propagating combo box selection down the ADF tree table.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<object style="height: 390px; width: 640px;"><param name="movie" value="http://www.youtube.com/v/f7qzuhMHKTs?version=3&feature=player_detailpage">
<param name="allowFullScreen" value="true">
<param name="allowScriptAccess" value="always">
<embed src="http://www.youtube.com/v/f7qzuhMHKTs?version=3&feature=player_detailpage" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="640" height="360"></object>
</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
Related: documentation on how to <a href="http://docs.oracle.com/cd/E23943_01/web.1111/b31974/adv_ads.htm">enable ADS</a><br />
<br />
Sample project: <a href="http://bit.ly/LXmqxx">http://bit.ly/LXmqxx </a><br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
Note: the sample project uses slightly modified HR schema, please run the script on it:<br />
<br />
<div style="font-family: Helvetica; font-size: 13px;">
<span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">ALTER</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">TABLE</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: olive; font-family: Arial, sans-serif; font-size: 10pt;">DEPARTMENTS</span><o:p></o:p></div>
<div style="font-family: Helvetica; font-size: 13px;">
<span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">ADD</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">(</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;">DEPARTMENT_CONFIRMED </span><span style="color: red; font-family: Arial, sans-serif; font-size: 10pt;">VARCHAR2</span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">(</span><span style="color: maroon; font-family: Arial, sans-serif; font-size: 10pt;">1</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">BYTE));</span><o:p></o:p></div>
<div style="font-family: Helvetica; font-size: 13px;">
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">ALTER</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">TABLE</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: olive; font-family: Arial, sans-serif; font-size: 10pt;">EMPLOYEES</span><o:p></o:p></div>
<div style="font-family: Helvetica; font-size: 13px;">
<span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">ADD</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">(</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;">EMPLOYEE_CONFIRMED </span><span style="color: red; font-family: Arial, sans-serif; font-size: 10pt;">VARCHAR2</span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">(</span><span style="color: maroon; font-family: Arial, sans-serif; font-size: 10pt;">1</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">BYTE));</span><o:p></o:p></div>
<div style="font-family: Helvetica; font-size: 13px;">
<span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">ALTER</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">TABLE</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: olive; font-family: Arial, sans-serif; font-size: 10pt;">LOCATIONS</span><o:p></o:p></div>
<div style="font-family: Helvetica; font-size: 13px;">
<span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">ADD</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">(</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;">LOCATION_CONFIRMED </span><span style="color: red; font-family: Arial, sans-serif; font-size: 10pt;">VARCHAR2</span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">(</span><span style="color: maroon; font-family: Arial, sans-serif; font-size: 10pt;">1</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">BYTE));</span><o:p></o:p></div>
<div style="font-family: Helvetica; font-size: 13px;">
<span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">ALTER</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">TABLE</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: olive; font-family: Arial, sans-serif; font-size: 10pt;">COUNTRIES</span><o:p></o:p></div>
<div style="font-family: Helvetica; font-size: 13px;">
<span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">ADD</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">(</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;">COUNTRY_CONFIRMED </span><span style="color: red; font-family: Arial, sans-serif; font-size: 10pt;">VARCHAR2</span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">(</span><span style="color: maroon; font-family: Arial, sans-serif; font-size: 10pt;">1</span><span style="color: black; font-family: Arial, sans-serif; font-size: 10pt;"> </span><span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;">BYTE));</span><o:p></o:p></div>
<div>
<span style="color: blue; font-family: Arial, sans-serif; font-size: 10pt;"><br /></span></div>Jernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.com0tag:blogger.com,1999:blog-3140073780907992078.post-67288467661777694602012-03-22T22:06:00.001+01:002012-03-22T22:06:37.133+01:00Learn about the biggest ADF project - Oracle Fusion Applications<p> Oracle Fusion Applications <a href="https://blogs.oracle.com/scm/entry/oracle_fusion_applications_data_sheets" target="_self" title="">datasheets are now available</a></p><p>Fusion Apps are probably the biggest ADF project out there and they showcase the ability and strategic value of ADF for Oracle.</p><p> </p>Jernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.com0tag:blogger.com,1999:blog-3140073780907992078.post-34209713594543982262012-02-12T17:24:00.001+01:002012-02-12T18:16:31.647+01:00Alternative Sequence assignment in ADF BCOut of the box ADF BC provides at least two options for assigning sequence values to ID fields:<br />
<br />
<b>DBSequence</b> assigns temporary unique values to newly created entities and fetches the actual ID (assigned by a database trigger) by using <i>returning </i>clause.<br />
This works quite OK, but I had situations, where DBSequence misbehaved, specially in master-detail scenarios where you create parent and child record(s) in one transaction. Also, working with integers is simpler.<br />
<br />
<b>Using groovy </b>expression like the one below gets rid of DBSequence, but introduces an extra round-trip at the time when a new row is created, which might not be the best idea performance-wise.<br />
<script class="brush: java" type="syntaxhighlighter">
<![CDATA[
(new oracle.jbo.server.SequenceImpl
("EMPLOYEES_SEQ", object.getDBTransaction())).getSequenceNumber()
]]>
</script>
<br />
<b>Using In-memory singleton sequencer</b><br />
As an alternative, we can use an In-memory singleton sequencer initialized from DB sequence used across entities.<br />
<br />
First, we need to define a <b>database sequence</b>. Since we are not querying it for each and every value, we increment it in reasonable steps, let's say 100.<br />
<script class="brush: sql" type="syntaxhighlighter">
<![CDATA[
CREATE SEQUENCE HR_SEQ
START WITH 10000
INCREMENT BY 100;
]]>
</script>
<br />
Next, we create a<b> singleton</b> <b>for serving sequences</b> to our entities<br />
<script class="brush: java" type="syntaxhighlighter">
<![CDATA[
package si.kase.sample.model.framework;
import oracle.jbo.server.DBTransaction;
import oracle.jbo.server.SequenceImpl;
/**
* In-memory singleton sequence generator, initialized by database sequence
* Decreases round-trips to database and use of DBSequence
*
* @author Jernej Kase (jernej@kase.si)
*/
public enum Sequencer {
INSTANCE;
private long _currentValue=-1;
private int _count=0;
private final int INCREMENT=99;
/**
*
* @param transaction DBTransaction used to fetch next sequence value
* @return
*/
public synchronized long getNextSequenceValue(DBTransaction transaction) {
if(_currentValue==-1 || _count==INCREMENT) rebase(transaction);
_count++;
return _currentValue++;
}
private synchronized void rebase(DBTransaction transaction) {
_currentValue=getNextSequenceFromDB(transaction);
_count=0;
}
private synchronized long getNextSequenceFromDB(DBTransaction transaction) {
SequenceImpl seq = new SequenceImpl("HR_SEQ", transaction);
return seq.getSequenceNumber().longValue();
}
}
]]>
</script>
<br />
And a <b>custom base EntityImpl</b> exposing singleton to entity.<br />
Don't forget to configure Business components to use custom base class in project properties!<br />
<script class="brush: java" type="syntaxhighlighter">
<![CDATA[
package si.kase.sample.model.framework;
/**
* Custom EntityImpl with support for in-memory sequencer
*
* Set this class as base class for Entities in:
* Project properties -> ADF Business Components -> Base Classes
*
* Also make sure your Entitiy xml source includes
* RowClass="si.kase.sample.model.framework.EntityImpl" attribute
*
* @author Jernej Kase (jernej@kase.si)
*/
public class EntityImpl extends oracle.jbo.server.EntityImpl {
public EntityImpl() {
super();
}
/**
* Call this method from entity attribute with groovy expression:
* object.getNextSequenceValue()
* to assign next sequence value
*/
public long getNextSequenceValue() {
return Sequencer.INSTANCE.getNextSequenceValue(getDBTransaction());
}
}
]]>
</script>
<br />
<b>Usage </b>is very simple, just add the groovy expression below as attribute's Default value expression.<br />
<script class="brush: java" type="syntaxhighlighter">
<![CDATA[
object.getNextSequenceValue()
]]>
</script>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-chtWcc_DHpU/TzftWrnO_NI/AAAAAAAABu0/ID5eAs65UsI/s1600/groovy_sequencer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="232" src="http://2.bp.blogspot.com/-chtWcc_DHpU/TzftWrnO_NI/AAAAAAAABu0/ID5eAs65UsI/s400/groovy_sequencer.png" width="400" /></a></div>
<br />
<b>Some thoughts about this method</b><br />
First of all, the singleton might not really be singleton. If you package the same class in multiple EARs, you will get more than one instance. Also, running on multiple servers will result in multiple instances. The instances can also die or are garbage collected before they serve all the sequences they reserve. <br />
But none of that should be a problem. Remember, you can get gaps in sequences even in the database anyway, so you should not count on them being sequential. The singleton will server unique numbers regardless how many instances there actually are.
<br />
<br/>
<b>Download sample code</b><br />
<a href="http://goo.gl/EmPvV">SequencerSampleApp</a>Jernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.com0tag:blogger.com,1999:blog-3140073780907992078.post-41759741750456910512011-10-04T21:13:00.005+01:002011-10-12T08:21:55.461+01:00ADF @ Oracle Open World 2011<b>This is a life changing Open World for ADF!</b><br />
<b><br />
</b><br />
<b>ADF Mobile</b> will change the way how we develop business apps for mobile. The big news here is that <u>it's supposed to include a small JVM that Apple will allow on iOS!</u> Fallback is HTML5.<br />
<br />
The supported platforms are <b>Android</b> and <b>iPhone/iPad</b> (required version unknown at this time).<br />
<br />
It will be possible to access device features like GPS, SMS etc.. It will support offline mode with SQLite storage.<br />
<br />
I can wait to get my hands on this!<br />
<br />
<br />
Some examples: (photos courtesy of Wilfred vander Deijl):<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-BLtWCYH7jAQ/ToysQhMIAXI/AAAAAAAAA-Q/74eCFYQmO7E/s1600/adf_mobile2.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="191" src="http://3.bp.blogspot.com/-BLtWCYH7jAQ/ToysQhMIAXI/AAAAAAAAA-Q/74eCFYQmO7E/s200/adf_mobile2.jpg" width="200" /></a></div><a href="http://3.bp.blogspot.com/-ZSPAoFRxH8s/ToysR6NjFSI/AAAAAAAAA-U/DY3hVADc8i8/s1600/adf_mobile1.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="191" src="http://3.bp.blogspot.com/-ZSPAoFRxH8s/ToysR6NjFSI/AAAAAAAAA-U/DY3hVADc8i8/s200/adf_mobile1.jpg" width="200" /></a><br />
<a href="http://3.bp.blogspot.com/-ZSPAoFRxH8s/ToysR6NjFSI/AAAAAAAAA-U/DY3hVADc8i8/s1600/adf_mobile1.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><br />
<div class="separator" style="clear: both; text-align: center;"></div>ADF Mobile <a href="http://www.oracle.com/ocom/groups/public/@otn/documents/webcontent/513078.pdf">data sheet is nov available</a>. According to it, the planned release date for ADF Mobile is in 2012.<br />
<br />
<b>Run ADF apps in a cloud</b><br />
<br />
with Oracle Public Cloud. This is huge. Again, this opens a whole new range of possibilities, for everybode, from independent developers and large ISVs. Check <a href="http://cloud.oracle.com/mycloud/f?p=service:java_features:0:::::">http://cloud.oracle.com/mycloud/f?p=service:java_features:0:::::</a> for details.<br />
<br />
<br />
The Word has it that <b>ADF Community Edition</b> is around the corner. It's supposed to include almost anything but DVT components and will run on Glassfish among other app servers. It's not clear yet if it is going to be available for free or not.<br />
<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: x-small;">Disclaimer: I'm not @ OOW, just trying to compile all the cool stuff that's out there. This information could be completely wrong :-)</span>Jernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.com0tag:blogger.com,1999:blog-3140073780907992078.post-63837555333932986072011-09-26T21:42:00.000+01:002011-09-26T21:42:24.900+01:00ADF @ SIOUG 2011Last week (September 19-21), there was annual Slovenian OUG conference and I'm happy to see ADF being more and more present as ADF community grows around here.<div><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="http://www.sioug.si/images/phocagallery/SIOUG-2011/ponedeljek-19-09-2011/thumbs/phoca_thumb_l_img_7060%20large.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://www.sioug.si/images/phocagallery/SIOUG-2011/ponedeljek-19-09-2011/thumbs/phoca_thumb_l_img_7060%20large.jpg" width="216" /></a></div><div><br />
</div><div>The highlight (for the ADF part) were 2 sessions by Frank Nimphius, one was an overview and the business benefits of ADF, and the other more technical, focused on task flows.</div><div><br />
</div><div>I presented two sessions, showing how using ADF expands your opportunities to mobile market, while the other was about WebCenter and Enterprise 2.0.</div><div><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://fbcdn-sphotos-a.akamaihd.net/hphotos-ak-snc7/s720x720/309510_10150319243264644_771974643_7714291_131718807_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://fbcdn-sphotos-a.akamaihd.net/hphotos-ak-snc7/s720x720/309510_10150319243264644_771974643_7714291_131718807_n.jpg" width="320" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="http://www.sioug.si/images/phocagallery/SIOUG-2011/sreda-21-09-2011/thumbs/phoca_thumb_l_img_7882%20large.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="http://www.sioug.si/images/phocagallery/SIOUG-2011/sreda-21-09-2011/thumbs/phoca_thumb_l_img_7882%20large.jpg" width="320" /></a></div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://fbcdn-sphotos-a.akamaihd.net/hphotos-ak-ash4/s720x720/312062_10150320351879644_771974643_7722318_611736192_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://fbcdn-sphotos-a.akamaihd.net/hphotos-ak-ash4/s720x720/312062_10150320351879644_771974643_7722318_611736192_n.jpg" width="320" /></a></div><div><br />
</div><div><br />
</div><div>Andrej Maver and Uroš Furlič presented their experience with porting ADF 10g application to an alternative application server.</div><div><br />
</div><div><br />
</div><div>I know of some interesting ADF projects currently going on in Slovenia and I'm sure next year we'll have even more sessions success stories. As I heard, one partner just ditched WebSphere + Eclipse in favor of WebLogic+ADF+JDev, and their productivity has increased by a factor of 6!</div><div><br />
</div><div>See you all next year!</div><div><br />
</div>Jernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.com0tag:blogger.com,1999:blog-3140073780907992078.post-10079543519054903822011-06-08T16:35:00.000+01:002011-06-08T16:35:32.312+01:00JDeveloper 11.1.2 - wow, just wowJDeveloper 11.1.2 <a href="http://www.oracle.com/technetwork/developer-tools/jdev/overview/index.html">has been released</a> and it brings <a href="http://www.oracle.com/technetwork/developer-tools/jdev/jdev-11gr2-nf-404365.html">so many changes</a> that it could easily be called 12g.<br />
<br />
I'll go over new capabilities in the next few weeks, but for today a change that really changes the developer experience tremendously.<br />
<br />
<b>Hot Deployment</b><br />
<br />
With JDeveloper 11.1.2 "<a href="http://xkcd.com/303/">I'm redeploying</a>" excuse is no more!<br />
<br />
Hot deployment enables us to make changes to any layer in the project - be it model, bindings or view, recompile and simply refresh the page to get the results!<br />
<br />
See it in action:<br />
<div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/AzHQjHBJiTI?feature=player_embedded' frameborder='0'></iframe></div>Jernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.com1tag:blogger.com,1999:blog-3140073780907992078.post-18549258133708193572011-04-03T12:00:00.001+01:002011-04-03T12:01:25.348+01:00JDeveloper - accessing brackets on some keyboard layoutsSome keyboard layouts (Slovenian, Croatian and Serbian) use AltGr-n for } and AltGr-f for [ characters.<br />
By default, these characters are not accessible in JDeveloper, which is quite annoying.<br />
<br />
<b>Fix</b><br />
Go to Tools->Preferences, navigate to "Shortcut Keys".<br />
In the search box, enter "ctrl-alt-f" and remove assigned actions. Repeat for "ctrl-alt-n" combination.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-7bWlp8Sr-2U/TZhTEhoBbEI/AAAAAAAAAEY/lup9cYs9GPQ/s1600/brackets_fix.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="228" src="http://3.bp.blogspot.com/-7bWlp8Sr-2U/TZhTEhoBbEI/AAAAAAAAAEY/lup9cYs9GPQ/s320/brackets_fix.PNG" width="320" /></a></div>Jernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.com0tag:blogger.com,1999:blog-3140073780907992078.post-11147667588801705932011-03-31T11:51:00.000+01:002011-03-31T11:51:11.428+01:00Avoiding ADF loopback script in servletsA few versions ago ADF introduced a loopback script which is returned to client the first time an URL is accessed.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-d0LSkD94y2E/TZRYE1SutdI/AAAAAAAAAEM/bElFBzoppK4/s1600/loopback.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="266" src="http://4.bp.blogspot.com/-d0LSkD94y2E/TZRYE1SutdI/AAAAAAAAAEM/bElFBzoppK4/s400/loopback.PNG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ADF Loopback script</td></tr>
</tbody></table><br />
<b>The problem is, </b>when you want to serve binary content -such as images- from a servervlet, and you need access to FacesContext in that servlet, you need to call the servlet from within /faces/ URL, or FacesContext.getCurrentIstance() returns null:<br />
<br />
<span class="Apple-style-span" style="font-family: monospace;">Pointing browser to http://localhost:7101/myapp/imageservlet?empId=72</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-934oDQNJVLI/TZRZzdBiwMI/AAAAAAAAAEU/RQ9jqKIm7kk/s1600/no_faces.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="75" src="http://1.bp.blogspot.com/-934oDQNJVLI/TZRZzdBiwMI/AAAAAAAAAEU/RQ9jqKIm7kk/s320/no_faces.PNG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Accessing imageservlet without /faces leaves us with null faces context.</td></tr>
</tbody></table><span class="Apple-style-span" style="font-family: monospace;"><br />
</span><br />
The obvious thing to do is to access the servlet using <span class="Apple-style-span" style="font-family: monospace;">http://localhost:7101/myapp/faces/imageservlet?empId=72</span> . But if we do this, the loopback script is returned to client by ADF framework.<br />
<br />
Now imagine having a html page with <span class="Apple-style-span" style="font-family: monospace;"><img src="http://localhost:7101/myapp/faces/imageservlet?empId=72"> </span> tag. The image will not be rendered, since it will receive loopback script as image source.<br />
<br />
<b>The workaround</b> is quite simple. Turns out adf loopack script is not generated for some requests, including requests for jpg, png, js, css... So all we need to do is change the request url a bit (assuming the servlet listens to /imageservlet/*). Just append a dummy "/image.jpg" after the servlet url and voila, loopback is gone.<br />
<br />
<span class="Apple-style-span" style="font-family: monospace;"><img src="http://localhost:7101/myapp/faces/imageservlet/image.jpg?empId=72"></span><br />
<br />
Note that the first request will still generate 302 redirect, but that will not affect image rendering.Jernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.com2tag:blogger.com,1999:blog-3140073780907992078.post-60332588311460513352011-01-25T21:50:00.001+01:002011-01-25T21:57:12.656+01:00Increase market share by beating competitors. Even on IBM Web Sphere.Do you see an opportunity to sell a product or a custom software solution to an IBM WebSphere customer?<br />
<br />
Would you like to beat the competitors by providing:<br />
- much better time to market<br />
- an agile solution that you will be able to rapidly tailor to customer's ever changing needs<br />
- low maintenance costs<br />
- future-proof technology?<br />
<br />
Do you already have an ADF 11g solution that you can only bundle with WebLogic?<br />
<br />
Since version 11.1.1.4.0 (11g R1 patch set 3), <b>ADF is certified for IBM WebShpere</b>!<br />
<br />
If you would like to try and evaluate what ADF can do for you, go to <a href="http://www.oracle.com/technetwork/developer-tools/jdev/overview/jdeveloper-reviewrguide-086026.html">ADF Reviewer's Guide</a> to get started.Jernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.com0tag:blogger.com,1999:blog-3140073780907992078.post-51276626387244268942010-12-23T21:14:00.003+01:002010-12-23T21:24:27.949+01:00Extending WebLogic Virtual Edition for ADFWebLogic virtual edition, or rather, WebLogic on top of JRockit VE is an amazing technology. It makes operating system in virtualized environment obsolete.<br />
<br />
Forget about setting up latest OS version, patches, drivers, packages, firewall, anti-virus. Forget about configuring OS for application server. In short, forget about managing OS all together.<br />
<br />
<u>With JRockit VE, managing OS is the thing of the past.</u><br />
<br />
<b>How is it used</b><br />
<br />
You deploy a file based file system onto Oracle VM server, type<br />
<code>xm create -c vm.cfg</code><br />
and you are good to go.<br />
<br />
<b>How to get it running - step by step</b><br />
<div class="separator" style="clear: both; text-align: center;"></div><br />
<ol><li> <a href="http://edelivery.oracle.com/oraclevm">Download</a> and install Oracle VM<br />
Don't worry, If you don't have a server available, you can actually install Oracle VM inside VirtualBox! I'm not sure which settings are required, but I have:<br />
- System/Motherboard/Enable IO APIC = yes<br />
- System/Processor/Enable PAE/NX = no<br />
- System/Acceleration/Enable VT-x/AMD-V = yes<br />
- System/Acceleration/Enable Enable Nested Paging = yes<br />
There's nothing special regarding Oracle VM installation, you can use default settings.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/_k80_3qSdcVY/TRN_rQH_xHI/AAAAAAAAAD8/hvnD1hxPWKI/s1600/oraclevm_vbox.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="215" src="http://3.bp.blogspot.com/_k80_3qSdcVY/TRN_rQH_xHI/AAAAAAAAAD8/hvnD1hxPWKI/s320/oraclevm_vbox.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">OracleVM inside Oracle VirtualBox</td></tr>
</tbody></table></li>
<li><a href="http://www.oracle.com/technetwork/middleware/weblogic/virtualizationoption-086836.html">Download</a><b> </b>WebLogic with JRockit VE<br />
Unpack the zip somewhere on your disk. You'll find a folder wlsvePackage with a wlsveimagetool.jar tool and wlsve folder with the actual disk image and config file for the virtual machine.</li>
<li>If you don't have it, also <a href="http://www.java.com/en/download/index.jsp">download</a> and install Java runtime</li>
<li>Prepare machine to run with default domain<br />
- Open command line / terminal and go to the wlsvePackage folder where you unpacked the WebLogic VE and run<br />
<code>java -jar wlsveimagetool.jar -r ./wlsve/vm.cfg get config wlsve.xml</code><br />
to extract default WebLogic configuration from the system.img file<br />
- open the wlsve.xml file with your favorite editor and change the java-arguments element to <code><java-arguments>-cp $JAVA_HOME/lib/tools.jar:/jrockitve/lib/common.jar:/application/patch_wls1032/profiles/default/sys_manifest_classpath/weblogic_patch.jar:/application/wlserver_10.3/server/lib/weblogic.jar -Dweblogic.Name=WlsveAdmin -Dweblogic.Domain=wlsve_domain -Dweblogic.management.username=weblogic -Dweblogic.management.password=weblogic1 -Dweblogic.management.GenerateDefaultConfig=true weblogic.Server</java-arguments></code> This config will create the default wlsve_domain. Without the <i>Dweblogic.management.GenerateDefaultConfig=true option</i>, the domain isn't found and it won't work.</li>
<li>Write the config back to the virtual machine with <code>java -jar wlsveimagetool.jar -r ./wlsve/vm.cfg set config wlsve.xml</code></li>
<li>Transfer server.img and vm.cfg from ./wlsve folder to the Oracle VM<br />
You can either use ssh file transfer or copy the image to USB drive and connect and mount usb drive to the virtual machine.<br />
- <b>Make sure</b> you copy system.img and vm.cfg to the<b> /OVS/seed_pool/wlsve_domain_WlsveAdmin/ </b>folder on the Oracle VM server as this is the location specified in vm.cfg by default.</li>
<li>Start virtual machine with <code>xm create -c vm.cfg</code></li>
</ol><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/_k80_3qSdcVY/TROCBp2QA3I/AAAAAAAAAEA/DTmIQNO7a3s/s1600/jrockitvm.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="285" src="http://1.bp.blogspot.com/_k80_3qSdcVY/TROCBp2QA3I/AAAAAAAAAEA/DTmIQNO7a3s/s400/jrockitvm.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Booting JRockit VE</td></tr>
</tbody></table>With this configuration you will create a new weblogic domain and run it. You can connect to console and deploy standard Java EE applications, but not ADF, since the bundled WebLogic is not extended for ADF.<br />
<br />
<b>Extending WebLogic Virtual Edition for ADF</b><br />
<br />
For this step you absolutely need linux. If you don't have it, I suggest downloading Ubuntu and installing it into VirtualBox virtual machine.<br />
<br />
Why linux? It turns out that system.img is file-based file system, and that's what we are going to exploit*.<br />
<br />
<ol><li>Start with a fresh system.img and wlsve.xml. Unpack the system.img again if you made the above changes</li>
<li>Open command line / terminal and go to the wlsvePackage folder where you unpacked the WebLogic VE and run <code>java -jar wlsveimagetool.jar -r ./wlsve/vm.cfg get config wlsve.xml</code></li>
<li>Replace wlsve.xml with<code><?xml version="1.0" encoding="UTF-8"?><br />
<br />
<jrockitve-imagetool-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="jrockitve-imagetool-config.xsd" version="5.1"><br />
<jrockitve-config memory="1024" cpus="1"><br />
<storage><br />
<disks><br />
<disk id="root" size="3072 MB"/><br />
</disks><br />
<mounts><br />
<mount><br />
<mount-point>/</mount-point><br />
<disk>root</disk><br />
</mount><br />
</mounts><br />
</storage><br />
<vm-name>wlsve</vm-name><br />
<working-dir>/application/user_projects/domains/wlsve_domain</working-dir><br />
<java-arguments>-cp /application/patch_wls1032/profiles/default/sys_manifest_classpath/weblogic_patch.jar:/jrockitve/jrockit/jre/lib/tools.jar:/application/utils/config/10.3/config-launch.jar:/application/wlserver_10.3/server/lib/weblogic_sp.jar:/application/wlserver_10.3/server/lib/weblogic.jar:/application/modules/features/weblogic.server.modules_10.3.2.0.jar:/application/wlserver_10.3/server/lib/webservices.jar:/application/modules/org.apache.ant_1.7.0/lib/ant-all.jar:/application/modules/net.sf.antcontrib_1.0.0.0_1-0b2/lib/ant-contrib.jar:/application/oracle_common/modules/oracle.jrf_11.1.1/jrf.jar:/application/wlserver_10.3/common/eval/pointbase/lib/pbclient57.jar:/application/wlserver_10.3/server/lib/xqrl.jar -Dweblogic.Name=AdminServer -Djava.security.policy=/application/wlserver_10.3/server/lib/weblogic.policy -Xverify:none -da -Dplatform.home=/application/wlserver_10.3 -Dwls.home=/application/wlserver_10.3/server -Dweblogic.home=/application/wlserver_10.3/server -Ddomain.home=/application/user_projects/domains/wlsve_domain -Dcommon.components.home=/application/oracle_common -Djrf.version=11.1.1 -Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.Jdk14Logger -Djrockit.optfile=/application/oracle_common/modules/oracle.jrf_11.1.1/jrocket_optfile.txt -Doracle.domain.config.dir=/application/user_projects/domains/wlsve_domain/config/fmwconfig -Doracle.server.config.dir=/application/user_projects/domains/wlsve_domain/config/fmwconfig/servers/AdminServer -Doracle.security.jps.config=/application/user_projects/domains/wlsve_domain/config/fmwconfig/jps-config.xml -Djava.protocol.handler.pkgs=oracle.mds.net.protocol -Digf.arisidbeans.carmlloc=/application/user_projects/domains/wlsve_domain/config/fmwconfig/carml -Digf.arisidstack.home=/application/user_projects/domains/wlsve_domain/config/fmwconfig/arisidprovider -Dweblogic.alternateTypesDirectory=/modules/oracle.ossoiap_11.1.1,/modules/oracle.oamprovider_11.1.1 -Dweblogic.jdbc.remoteEnabled=false -Dweblogic.management.discover=true -Dwlw.iterativeDev= -Dwlw.testConsole= -Dwlw.logErrorsToConsole= -Dweblogic.ext.dirs=/application/patch_wls1032/profiles/default/sysext_manifest_classpath weblogic.Server</java-arguments><br />
<network><br />
<nics><br />
<nic type="bridged"/><br />
</nics><br />
</network><br />
<locale-data><br />
<locale>en_US</locale><br />
<timezone>America/New_York</timezone><br />
<encoding>ISO-8859-1</encoding><br />
</locale-data><br />
</jrockitve-config><br />
</jrockitve-imagetool-config></code><br />
</li>
<li>run <code>java -jar wlsveimagetool.jar -r ./wlsve/vm.cfg set config wlsve.xml</code>to write the changes to the system.img. This will:<br />
- enlarge the disk size to 3GB<br />
- run WebLogic with all the ADF libraries once we install them</li>
<li>If you use linux on VirtualBox, I suggest sharing your windows folder where you unpacked WebLogic with shared folders feature. You need to install vbox additions for it to work properly.<br />
- Share the folder, open terminal and mount it with<code>sudo mount -w -t vboxsf <i>share_name</i> /media/<i>oracle</i>/</code> where <i>share_name</i> is the name of your vbox shared folder and <i>oracle</i> is your mount point inside /media</li>
<li>cd to wlsve folder with system.img file and check and resize the filesystem in the image file <code>sudo e2fsck -f ./system.img<br />
sudo resize2fs ./system.img</code></li>
<li>Mount the file system with <code>sudo mount -o loop=/dev/loop0 ./system.img /media/<i>wlsve.img</i>/</code> where <i>wlsve.img </i>is your mount point</li>
<li>Since we can only extend the domain as non-root user, we need to change permissions on the filesystem <code>sudo chown -R <i>jernej</i> /media/wlsve.img/</code> <i>jernej</i> is your linux username. To my knowledge this is harmless, as it seems permissions are not used by JRockitVM at all (of course, there is no OS to handle security, remember).</li>
<li>I found no easy way of extending the mounted WebLogic home. Symbolic link doesn't work since installer writes the whole path with /media/wlsve.img. The easiest seem to be copying home to the /, extend it, create domain and copy it back<br />
- Copy weblogic home to root folder <code>sudo cp -R /media/wlsve.img/application /application<br />
sudo chown -R <i>user</i> /application </code><br />
- Copy jrockit home to root folder to simulate runtime environment <code>sudo cp -R /media/wlsve.img/jrockitve /jrockitve<br />
sudo chown -R <i>user</i> /jrockitve</code></li>
<li>Now <a href="http://www.blogger.com/goog_872626027">download and run </a><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: 12px; font-weight: bold; line-height: 14px;"><a href="http://www.oracle.com/technetwork/middleware/downloads/fmw-11-download-092893.html">Application Development Runtime (11.1.1.2.0)</a> . </span>Note that the bundled WebLogic does not support 11.1.1.3 runtime.<br />
- When installing the runtime, <b>make sure you chose /application</b> as your WebLogic home</li>
<li>Execute the domain configuration wizard <code>sudo chmod +x /application/wlserver_10.3/common/bin/config.sh<br />
/application/wlserver_10.3/common/bin/config.sh</code><br />
- Create a new domain <b>called wlsve_domain inside /application/user_projects/domains</b><br />
- When choosig JRE, <b>make sure you select the one under /jrockitve</b></li>
<li>Move your local copy of the domain back to the system.img <code>rm -rf /media/wlsve.img/application<br />
cp -R /application /media/wlsve.img/application </code></li>
<li>Unmount the image file <code>sudo umount /media/wlsve.img</code></li>
<li>Copy system.img to Oracle VM, and start the domain</li>
</ol><div>If everything is OK, your ADF-extended domain should be up and running inside JRockitVM! How cool is that!<br />
<br />
<br />
<div><br />
</div></div><br />
*The <a href="http://download.oracle.com/docs/cd/E17090_01/web.1111/e15219/deployvms.htm#CHDBCJCI">documentation</a> suggests a bit different approach, but I found this the easiest way of doing it.Jernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.com1tag:blogger.com,1999:blog-3140073780907992078.post-23522061194996534412010-10-26T17:46:00.001+01:002010-10-29T09:18:08.588+01:00ADF Challenge in Cyprus - boost your productivity by a factor of 15!On 25th and 26th of October we conducted another ADF workshop, this time in Cyprus.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/_k80_3qSdcVY/TMbW7yBweNI/AAAAAAAAADY/cuz4OXaJYh8/s1600/cy1.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="http://2.bp.blogspot.com/_k80_3qSdcVY/TMbW7yBweNI/AAAAAAAAADY/cuz4OXaJYh8/s640/cy1.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://antonis-antoniou.blogspot.com/">Antonis Antoniou</a> presenting ADF security and BI integration,<br />
Demetris Skourides, giving keynotes </td></tr>
</tbody></table><br />
This time, we challenged developers to give us estimates for an implementation of a simple set of requirements:<br />
- we are building a form for a business application<br />
- the form must implement all CRUD operations<br />
- data lookup fields<br />
- we want to present a master-detail relation, for example an employee and their job history<br />
- users must be able to perform custom queries<br />
- we want validation on server and client side, including for example regexp for email validation<br />
- The model / business logic must be reusable, able to serve different type of client applications<br />
- The application must be web based and must use ajax (eg. to show detail records of selected master)<br />
<br />
The conceptual UI for the application should look something like this:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/_k80_3qSdcVY/TMbTHZFmF7I/AAAAAAAAADU/tN0lrs8D3mg/s1600/ui.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="523" src="http://1.bp.blogspot.com/_k80_3qSdcVY/TMbTHZFmF7I/AAAAAAAAADU/tN0lrs8D3mg/s640/ui.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Conceptual UI requirements</td></tr>
</tbody></table><br />
We also assume that the database for our form is already implemented. We got quite different <b>estimates</b> anywhere from 2 hours to 1 day. <b>Most developers agreed they'd need at least half a day</b>. So we challenged them: <b><span class="Apple-style-span" style="color: #cc0000;">do you want to see it being implemented in 10 minutes</span></b>?<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/_k80_3qSdcVY/TMbYoR_pAwI/AAAAAAAAADg/xHt4lj4DM4U/s1600/cy3.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="http://4.bp.blogspot.com/_k80_3qSdcVY/TMbYoR_pAwI/AAAAAAAAADg/xHt4lj4DM4U/s640/cy3.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The participants learned how to boost their productivity and develop forms up to 15 times faster according to their own estimates.</td></tr>
</tbody></table><br />
Some of them laughed, most of them thought we were joking, but they agreed, sure, show it. So<b> </b>we did. <b>I implemented a form implementing all these requirements in<span class="Apple-style-span" style="color: #cc0000;"> 8 minutes</span>, starting from scratch</b>.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/_k80_3qSdcVY/TMbaFg13CEI/AAAAAAAAADk/TJ0rNy7pyU0/s1600/adf.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="336" src="http://4.bp.blogspot.com/_k80_3qSdcVY/TMbaFg13CEI/AAAAAAAAADk/TJ0rNy7pyU0/s640/adf.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Challenge: can you implement a fully functional form in .Net in less than 8 minutes?</td></tr>
</tbody></table><br />
<br />
The challenge got the attention and at the end of the workshop, most participants strongly agreed that ADF could boost their productivity.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/_k80_3qSdcVY/TMbYX-kiWdI/AAAAAAAAADc/Hav7M6ib_ts/s1600/cy2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="http://4.bp.blogspot.com/_k80_3qSdcVY/TMbYX-kiWdI/AAAAAAAAADc/Hav7M6ib_ts/s640/cy2.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Jernej Kaše, challenging .Net developers and presenting benefits of ADF</td></tr>
</tbody></table><br />
Thanks to everyone for organizing the workshop, specially Antonis, Spyros, Demetris and StaloJernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.com0tag:blogger.com,1999:blog-3140073780907992078.post-65254000815627604222010-10-06T23:09:00.000+01:002010-10-06T23:09:00.712+01:00ADF productivity boost for Ajax enabled Master - Detail web pages<span class="Apple-style-span" style="font-family: Arial;"><span class="Apple-style-span">Last time <a href="http://jernejkase.blogspot.com/2010/09/net-attack-2992010-istanbul-turkey.html">I promised</a> a side-by-side .Net vs ADF comparison of Ajax enabled Master-Detail web pages.</span></span><br />
<span class="Apple-style-span" style="font-family: Arial;">So in this article, I'm going to compare the two and show how you can increase productivity by using ADF.</span><br />
<span class="Apple-style-span" style="font-family: Arial;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Arial;">This is the screenshot of the .Net example we are going to implement. Note that I'm focusing on functionality, not skinning here.</span><br />
<div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/_k80_3qSdcVY/TKyf7cKT4HI/AAAAAAAAACY/66PMbe27e2Q/s1600/asp_master_detail.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="326" src="http://3.bp.blogspot.com/_k80_3qSdcVY/TKyf7cKT4HI/AAAAAAAAACY/66PMbe27e2Q/s400/asp_master_detail.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Asp.Net master detail form example</td></tr>
</tbody></table><span class="Apple-style-span" style="font-family: Arial;">The form implements the following use cases:</span><br />
<ul><li>User can filter master records by clicking one of the A-Z buttons (names starts with the selected letter)</li>
<li>Selecting the master record loads the detail record(s)*</li>
</ul><div>*<span class="Apple-style-span" style="font-size: x-small;">I find the .Net sample app a bit out of place, as it is not true master detail app. If you take a look a the DAL, you'll see that Customer-Contact is 1-1 relation, since ContactName is simply a property of a Customer. So the example is really not implementing Master - detail, <a href="http://en.wikipedia.org/wiki/Master-detail">according to Wikipedia</a>. But still, it's a MSDN published, reference asp.net master-detail implementation.<br />
</span><br />
<span class="Apple-style-span" style="font-size: x-small;"></span>Please read <a href="http://msdn.microsoft.com/en-us/magazine/ee335720.aspx">the article</a> to learn how the .Net application is implemented. The general idea is:</div><div><ul><li>Implement DAL in business objects</li>
<li>Wrap DAL in data service</li>
<li>Create an asp.net web page, defining template for master and detail view</li>
<li>Load and show data by using MS Ajax library</li>
</ul><div><b><span class="Apple-style-span" style="font-size: x-large;">Implementing the example in ADF</span></b></div><div><b><span class="Apple-style-span" style="font-size: x-large;"><br />
</span></b><br />
<span class="Apple-style-span">Note: the sources for the resulting ADF application are available at google code: </span><span class="Apple-style-span" style="font-family: monospace; font-size: 13px;">svn checkout</span><span class="Apple-style-span" style="font-family: monospace; font-size: 13px;"> </span><span class="Apple-style-span" style="font-family: monospace; font-size: 13px;"><strong><em>http</em></strong></span><span class="Apple-style-span" style="font-family: monospace; font-size: 13px;">://adfcommunity.googlecode.com/svn/trunk/AdfMasterDetailDemo </span><span class="Apple-style-span" style="font-family: monospace; font-size: 13px;">adfcommunity-read-only</span><br />
<b><span class="Apple-style-span" style="font-size: x-large;"><br />
</span></b></div><div><b><span class="Apple-style-span" style="font-size: x-large;">1. Model</span></b></div><div>To implement Model (called Data Access Layer in .Net), we start by Creating Business Components from Tables. This automatically creates the model, with all CRUD method for us.</div><div><br />
</div><div><span class="Apple-style-span" style="font-size: small;">Note: since ADF sample is based on Oracle Database, I will use hr schema with Departments 1 - * Employees schema.</span></div><div><span class="Apple-style-span" style="font-size: small;"><br />
</span></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/_k80_3qSdcVY/TKy9NPz0SSI/AAAAAAAAACc/eszJAO_B6q4/s1600/model.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="http://2.bp.blogspot.com/_k80_3qSdcVY/TKy9NPz0SSI/AAAAAAAAACc/eszJAO_B6q4/s320/model.png" width="230" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Model (DAL) in ADF</td></tr>
</tbody></table><div>If you are coming from .Net this screenshot is a bit confusing. But for now, you should keep in mind that Business Components compare to Ado.Net datasets or Entity Framework Entities.</div><div><br />
</div><div><b>Coding so far:</b> 0</div><div><br />
</div><div>Now let's implement what's required for first use case: filtering by starts with criteria.</div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/_k80_3qSdcVY/TKzP8DJnLgI/AAAAAAAAACg/khY5kb8526k/s1600/viewcrit.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="http://2.bp.blogspot.com/_k80_3qSdcVY/TKzP8DJnLgI/AAAAAAAAACg/khY5kb8526k/s400/viewcrit.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">We define view criteria for Starts with query</td></tr>
</tbody></table></div><div>Then, by simply marking a checkbox we implement a custom class for our view object. Unlike .Net's partial class, in ADF overs full control and customization of data objects! And then we add a custom method to our ViewObject:<br />
<code><span class="Apple-style-span" style="font-family: monospace;">public void queryByStartsWithParam(String startsWith) {</span><br />
<span class="Apple-style-span" style="font-family: monospace;"> ViewCriteria vc=getViewCriteria("startsWithCriteria");</span><br />
<span class="Apple-style-span" style="font-family: monospace;"> ((Row)vc.getRows().toArray()[0]).setAttribute("DepartmentName",startsWith);</span><br />
<span class="Apple-style-span" style="font-family: monospace;"> applyViewCriteria(vc);</span><br />
<span class="Apple-style-span" style="font-family: monospace;"> executeQuery();</span><br />
<span class="Apple-style-span" style="font-family: monospace;"></span><span class="Apple-style-span" style="font-family: monospace;">}</span><br />
</code><br />
And finally, we expose our custom method to clients<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/_k80_3qSdcVY/TKzRvKEdaCI/AAAAAAAAACk/52WePYfqRdQ/s1600/itf.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="277" src="http://3.bp.blogspot.com/_k80_3qSdcVY/TKzRvKEdaCI/AAAAAAAAACk/52WePYfqRdQ/s400/itf.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Expose custom method to clients</td></tr>
</tbody></table><span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><b>Coding so far:</b></span><span class="Apple-style-span" style="font-family: 'Times New Roman';"> 6 LOC</span></span><br />
<span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><br />
</span></span><br />
<span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><b><span class="Apple-style-span" style="font-size: x-large;">2. User interface</span></b></span></span><br />
For general layout I created a page template which you'll find in source files. For those of you who don't know ADF suffices to say page template is similar to asp.net master pages. I didn't bother to create exactly the same layout, but it's fairly similar.<br />
<br />
We'll start by adding a panelSplitter to content facet, since it's very useful for master-detail pages. Then, we simply <b>drag and drop </b>DepartmentsView1 from DataControls to the panelSplitter, we create a table for our master data.<br />
<code><af:table value="#{bindings.DepartmentsView1.collectionModel}"<br />
var="row"<br />
rows="#{bindings.DepartmentsView1.rangeSize}"<br />
emptyText="#{bindings.DepartmentsView1.viewable ? 'No data to display.' : 'Access Denied.'}"<br />
fetchSize="#{bindings.DepartmentsView1.rangeSize}"<br />
rowBandingInterval="0"<br />
selectedRowKeys="#{bindings.DepartmentsView1.collectionModel.selectedRow}"<br />
selectionListener="#{bindings.DepartmentsView1.collectionModel.makeCurrent}"<br />
rowSelection="single" id="t1"<br />
horizontalGridVisible="false"<br />
verticalGridVisible="false"<br />
inlineStyle="border-style:none;margin-left:50px;"<br />
contentDelivery="immediate" displayRow="selected"><br />
<af:column sortProperty="DepartmentName" sortable="false"<br />
headerClass="noHeader" width="400" id="c1"><br />
<af:panelGroupLayout id="pgl1"><br />
<af:outputText value="#{viewcontrollerBundle.BULLET}" id="ot3"/><br />
<af:spacer width="15" height="5" id="s1"/><br />
<af:outputText value="#{row.DepartmentName}" id="ot2"<br />
styleClass="listText"/><br />
</af:panelGroupLayout><br />
</af:column><br />
</af:table><br />
</code><br />
Note that the above code is auto generated for us. We just modify it a bit to suite our needs (mostly design related).<br />
Next, we add detail form. We drag and drop Employees detail view from the Data Controls to the second facet of the panelSplitter and choos ADF form. We also add navigation buttons, just because we can. Here we change nothing but decorate our form with custom css style.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/_k80_3qSdcVY/TKzZIo1MuGI/AAAAAAAAACo/26gGTREiP4g/s1600/datacontrols.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="196" src="http://2.bp.blogspot.com/_k80_3qSdcVY/TKzZIo1MuGI/AAAAAAAAACo/26gGTREiP4g/s320/datacontrols.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Creating details form is a simple drag and drop operation.</td></tr>
</tbody></table><span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><b>Coding so far:</b></span></span><span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"> 6 LOC + a bit JSF tweaking. So where could this get us? Let's see.</span></span><br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/_k80_3qSdcVY/TKzbVyA2YcI/AAAAAAAAACs/ZnW-gbuyFBw/s1600/master-detail1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="315" src="http://3.bp.blogspot.com/_k80_3qSdcVY/TKzbVyA2YcI/AAAAAAAAACs/ZnW-gbuyFBw/s400/master-detail1.png" width="400" /></a></div><span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';">Well, turns out <b>we built a completely functional, Ajax enabled real Master - Detail web page</b>. When you select a record in master table the details are loaded using Ajax. Also, because this is true 1-* Master - Detail, we added navigation buttons to our detail records. How cool is that?</span></span><br />
<span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';">And please note, the 6 LOC we wrote weren't even used by now. So let's use it and finish the example.</span></span><br />
<span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><br />
</span></span><br />
<span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';">First we'll bind our web page to the </span></span><span class="Apple-style-span" style="font-family: monospace;">queryByStartsWithParam </span>method:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/_k80_3qSdcVY/TKzc567tZoI/AAAAAAAAACw/5hiXvTeRqzE/s1600/bindings.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="222" src="http://4.bp.blogspot.com/_k80_3qSdcVY/TKzc567tZoI/AAAAAAAAACw/5hiXvTeRqzE/s320/bindings.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Binding web page to custom function</td></tr>
</tbody></table>Then we add filter buttons:</div><code><br />
<af:commandButton text="A" id="commandButton1"<br />
styleClass="bar"<br />
actionListener="#{bindings.queryByStartsWithParam.execute}"<br />
partialSubmit="true"><br />
<af:setActionListener from="A"<br />
to="#{bindings.startsWith.inputValue}"/><br />
</af:commandButton><br />
</code><br />
<div>Note After adding all the buttons and cofiguring them to trigger partial Ajax page request, we got only one more thing to do: add the "Selected Departments" label:<br />
<code><br />
<af:outputText value="Selected customers: #{bindings.startsWith.inputValue}"<br />
id="ot6"<br />
inlineStyle="color:#76b7d7; font-size:1.4em; font-weight:bold;"<br />
partialTriggers="t1"/><br />
</code><br />
<b>Putting it all together:</b><br />
<div class="separator" style="clear: both; text-align: center;"></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/_k80_3qSdcVY/TKzi70_KgwI/AAAAAAAAAC8/VUB8Y1BnkG0/s1600/mdadf.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="323" src="http://2.bp.blogspot.com/_k80_3qSdcVY/TKzi70_KgwI/AAAAAAAAAC8/VUB8Y1BnkG0/s400/mdadf.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ADF master detail sample.</td></tr>
</tbody></table><b><span class="Apple-style-span" style="font-size: x-large;"><span class="Apple-style-span" style="font-size: medium; font-weight: normal;"><b><span class="Apple-style-span" style="font-size: x-large;">2. That's not all Folks!</span></b></span></span></b><br />
You know, the .Net example is fine and all, but it doesn't even mention two other issues:<br />
<br />
<ul><li>persisting changes and</li>
<li>data validation</li>
</ul><div>Sure, those are important building blocks. So important in fact, that MSDN runs <a href="http://msdn.microsoft.com/en-us/magazine/ee336022.aspx">another article</a> just on saving changes back to the server. More technology, more code.</div><div><br />
</div><div><b>But, we can do it all with just two simple drag and drops! </b>Let me show you how:</div><div>in the Data Controls, we'll find two operations: commit and rollback. Again, drag and drop them to our page and ADF will create buttons for us.</div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/_k80_3qSdcVY/TKzo6VsHQ3I/AAAAAAAAADA/21R7EjpePsQ/s1600/commit.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="151" src="http://3.bp.blogspot.com/_k80_3qSdcVY/TKzo6VsHQ3I/AAAAAAAAADA/21R7EjpePsQ/s320/commit.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Commit and Rollback operations become...</td></tr>
</tbody></table><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/_k80_3qSdcVY/TKzpRX1FB6I/AAAAAAAAADE/ju3HNZQ6VsY/s1600/commitbtn.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="142" src="http://1.bp.blogspot.com/_k80_3qSdcVY/TKzpRX1FB6I/AAAAAAAAADE/ju3HNZQ6VsY/s320/commitbtn.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">... Commit and Rollback buttons!</td></tr>
</tbody></table><div><span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><b>Coding so far:</b></span></span><span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"> 6 LOC. And yes, it's hard to believe, but that really is all we need to do to save the changes back to the database. Or discard them if we made a mistake.</span></span></div><div><span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><br />
</span></span></div><div><span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';">And again, just because we can, how about adding regular expression validation for email format?</span></span></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/_k80_3qSdcVY/TKzqWF1yzLI/AAAAAAAAADI/i2q6qwKoUXw/s1600/validation.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="http://3.bp.blogspot.com/_k80_3qSdcVY/TKzqWF1yzLI/AAAAAAAAADI/i2q6qwKoUXw/s400/validation.png" width="370" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Adding regexp validation for email address.</td></tr>
</tbody></table><div><span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';">And that's about it. Nothing else. When we try to save an invalid email address we get:</span></span></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/_k80_3qSdcVY/TKzq2NBorCI/AAAAAAAAADM/YE9HaO68_uM/s1600/error.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="113" src="http://3.bp.blogspot.com/_k80_3qSdcVY/TKzq2NBorCI/AAAAAAAAADM/YE9HaO68_uM/s400/error.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Out of the box validation</td></tr>
</tbody></table><div><span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><b>Coding so far:</b></span></span><span class="Apple-style-span" style="font-family: monospace;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"> 6 LOC, a few template tweaks and a validation rule. Can you top that?</span></span></div><div><br />
</div><br />
<b><span class="Apple-style-span" style="font-size: x-large;">3. Summary</span></b><br />
As we can see, we implemented a fully functional, Ajax enabled Master detail Web page with <b>only 6 lines of code <span class="Apple-style-span" style="font-weight: normal;">and some auto-generated layout tweaking</span>.</b><br />
<br />
When project just begins in .Net, finally displaying read-only web-pages, it's almost finished in ADF, since data validation and persistence are an essential parts of the framework.<br />
<br />
<b>No extra knowledge</b> of different platforms, technologies or APIs was necessary (Javascript, DOM, Jquery, MS Ajax library..).<br />
<br />
Consequently, ADF applications are <b>cheap to maintain </b>since codebase and technology scope is smaller compared to other platforms.<br />
<br />
The winner? ADF, hands down.</div></div>Jernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.com0tag:blogger.com,1999:blog-3140073780907992078.post-24710765310667294022010-10-02T23:36:00.001+01:002010-10-02T23:37:23.388+01:00Porting existing Forms application with C(R)UD stored procedures to ADFAt the last ADF Workshop, Mehmet asked if it is possible to <b>reuse ther existing CRUD stored procedures</b> while <b>porting their Forms solution to ADF</b>. In this post, I'll just cover CUD, as R is a bit more specific if we want to retain all the ADF BC goodies.<br />
<br />
Mehmet's existing CUD stored procedures have the following signatures:<br />
<code>SUBTYPE DEPARTMENTS_rt IS DEPARTMENTS%ROWTYPE;<br />
SUBTYPE DEPARTMENT_ID_t IS DEPARTMENTS.DEPARTMENT_ID%TYPE;<br />
<br />
PROCEDURE ins (rec_in IN DEPARTMENTS_TP.DEPARTMENTS_rt);<br />
PROCEDURE upd (rec_in IN DEPARTMENTS_TP.DEPARTMENTS_rt);<br />
PROCEDURE del (department_id_in IN DEPARTMENTS_TP.DEPARTMENT_ID_t);</code><br />
Many developers have worked on the code base and they didn't all follow the same naming convention for package and procedure names - that means we can not deduce procedure names simply from table or entity names.<br />
<br />
<b><span class="Apple-style-span" style="font-size: x-large;">The solution</span></b><br />
is quite simple. We need to override the doDml method and execute existing stored procedures. One of the problems is that Pl/Sql row type can't be mapped to Java easily. But - we can declare a row type variable and initialize each member before we call the procedure:<br />
<code>DECLARE <br />
rec_in DEPARTMENTS_TP.DEPARTMENTS_RT; <br />
BEGIN <br />
rec_in.DEPARTMENT_ID := ?; <br />
rec_in.DEPARTMENT_NAME := ?; <br />
rec_in.MANAGER_ID := ?; <br />
rec_in.LOCATION_ID := ?; <br />
DEPARTMENTS_CP.INS(rec_in); <br />
END;</code><br />
With this idea on hand, we can implement a Pl/Sql code generator in no time. <a href="https://code.google.com/p/adfcommunity/source/browse/trunk/AdfCrudSpDemo/Model/src/net/kinvent/crudsp/model/CudEntityImpl.java">CudEntityImpl</a> (click for complete listing) is a generic base class which fits the requirements. All a developer has to do is to extend his entities from this base class and specify (either through custom properties or by overriding procedure name getters) stored procedure names.<br />
<br />
You can download the complete sample project with subversion client:<br />
<span class="Apple-style-span" style="font-family: monospace;">svn checkout http://adfcommunity.googlecode.com/svn/trunk/AdfCrudSpDemo adfcommunity-read-only</span>Jernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.com0tag:blogger.com,1999:blog-3140073780907992078.post-69411837129989460682010-09-29T23:11:00.003+01:002010-09-29T23:23:05.793+01:00.Net Attack, 29.9.2010, Istanbul, Turkey<div class="separator" style="clear: both; text-align: left;">Thanks to Oracle Turkey, I held an ADF workshop for .Net developers in Istanbul.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">The .Net guys were really surprised by ADF capabilities. Or rather, .Net incapabilities.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">When we started the workshop and we discussed different frameworks, one of the guys stated that "Asp.Net is clearly the best framework for (enterprise) web applications." So we discussed this a little bit. Turns out, out of the box, you <b>can't do</b> the following things with Asp.Net, at least not without extensions and add-ons:</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">- Implement a Model / business logic + data access layer which you can easily reuse to implement web, desktop and mobile applications</div><div class="separator" style="clear: both; text-align: left;">- Implement a well defined set of business rules / validation in one layer, and consistently reuse it around your application without any additional coding</div><div class="separator" style="clear: both; text-align: left;">- Implement AJAX enabled master-detail data controls while maintaining an in-memory data consistency</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">Actually, I found <a href="http://msdn.microsoft.com/en-us/magazine/ee335720.aspx">this article</a> describing how to implement a part of the last item on the list. For those of you who know ADF it's laughable. For those who don't - I'll write another article comparing both solutions in the future.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;">At the end of the day, most of the attendees agreed that <b>development productivity </b>can increase at least <b>by a factor of 2</b> with ADF while the final application has superior <b>usablitiy </b>and ease of use.</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;"></div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;"><a href="http://1.bp.blogspot.com/_k80_3qSdcVY/TKNYGu3MIDI/AAAAAAAAACE/iOWpHRiXe-c/s1600/SDC11231.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://1.bp.blogspot.com/_k80_3qSdcVY/TKNYGu3MIDI/AAAAAAAAACE/iOWpHRiXe-c/s320/SDC11231.JPG" width="320" /></a></div><div style="text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;"><a href="http://4.bp.blogspot.com/_k80_3qSdcVY/TKNYSLGyMkI/AAAAAAAAACI/m8RUSaTU89M/s1600/SDC11232.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://4.bp.blogspot.com/_k80_3qSdcVY/TKNYSLGyMkI/AAAAAAAAACI/m8RUSaTU89M/s320/SDC11232.JPG" width="320" /></a></div><div style="text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;"><a href="http://2.bp.blogspot.com/_k80_3qSdcVY/TKNYeqS0PpI/AAAAAAAAACM/Soiu8xCPPE0/s1600/SDC11233.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://2.bp.blogspot.com/_k80_3qSdcVY/TKNYeqS0PpI/AAAAAAAAACM/Soiu8xCPPE0/s320/SDC11233.JPG" width="320" /></a></div><div style="text-align: left;"><br />
</div><div class="separator" style="clear: both; text-align: left;"><a href="http://4.bp.blogspot.com/_k80_3qSdcVY/TKNYqmRLT-I/AAAAAAAAACQ/hnd2VOUfkXI/s1600/SDC11234.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://4.bp.blogspot.com/_k80_3qSdcVY/TKNYqmRLT-I/AAAAAAAAACQ/hnd2VOUfkXI/s320/SDC11234.JPG" width="320" /></a></div><div style="text-align: left;"><br />
It was nice meeting you guys, I hope you start your first ADF projects soon!<br />
And special thanks to Sevgi for all the support.</div>Jernej Kašehttp://www.blogger.com/profile/13242054498110872927noreply@blogger.com2