tag:blogger.com,1999:blog-28274402521274117732024-03-14T05:32:16.772+02:00ADF Code BitsBits of code related to Oracle's Application Development Framework (ADF). Some of the posts in this blog may seem elementary. They are. Nevertheless, you will be amazed to find out how many beginner ADF practitioners are struggling with basic concepts and sample code. Hopefully they will find some here.Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.comBlogger41125tag:blogger.com,1999:blog-2827440252127411773.post-90372887492138857852017-02-13T17:19:00.000+02:002017-02-14T00:25:40.086+02:00Bit #40 - adfAuthentication servlet allow_logout_url_param parameter<div dir="ltr" style="text-align: left;" trbidi="on">
I was googling all over for some documentation on the <i><b>allow_logout_url_param_overwrite</b></i> initialization parameter of the <i><b>adfAuthentication </b></i>servlet in <i><b>web.xml</b></i> and guess what... (yes, you guessed right) I could not find anything on it. After digging into it, disassembling the library code and all, it turns out that this parameter is used in the following ADF code snippet in <b><i>oracle.adf.share.security.authentication.AuthenticationServlet</i></b> (the <i><b>adfAuthentication </b></i>servlet in <i><b>web.xml</b></i>):<br />
<br />
<i> if (session != null) {<br /> endUrl = (String)session.getAttribute(paramEndUrl); <br /> session.removeAttribute(</i><i><i>paramEndUrl</i>); <br /> }<br /><br /> if ((overwriteLogoutUrl || </i><i><i>endUrl </i>== null) && </i><i><i>parameters</i>.containsKey(</i><i><i>paramEndUrl</i>)) {<br /> String[] </i><i><i><i>paramEndUrlVals </i></i>= (String[]) parameters.get(</i><i><i>paramEndUrl</i>);<br /> </i><i><i>endUrl </i>= </i><i><i><i><i>paramEndUrlVals</i></i></i>[0];<br /> }</i><br />
<br />
As you can see from the above code, the <i><b>allow_logout_url_param_overwrite</b></i> parameter when set to "<i>true</i>" allows you to overwrite the logout URL (if one is specified during logout) with the one defined with the <i><b>end_url </b></i>parameter in <i><b>web.xml</b></i>.<br />
<br />
Another interesting tip is that when a logout URL is <u>not </u>specified during logout (<i>endUrl </i><i>== null</i> above), the one defined by the <i><b>end_url</b></i> parameter in <i><b>web.xml</b></i> (if one is defined) is used no matter what the value of the <i><b>allow_logout_url_param_overwrite</b></i> parameter is. Makes sense.<br />
<br />
That's all!</div>
Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com0tag:blogger.com,1999:blog-2827440252127411773.post-57228797617319033192012-12-06T21:23:00.000+02:002017-02-14T00:55:02.948+02:00Oracle JDeveloper 11gR2 Cookbook<div dir="ltr" style="text-align: left;" trbidi="on">
After almost a year of truly great effort by everyone involved, I am happy to announce that my <b><i>Oracle JDeveloper 11gR2 Cookbook</i></b> book is published by <b><i>Packt Publishing</i></b>.
This book accumulates to a large degree my practical experience amassed
over the last four years working on real world ADF projects.<br />
<br />
Special Thanks goes to <b><i>Frank Nimphius</i></b>, <b><i>Edwin Biemond</i></b> and <b><i>Spyros Doulgeridis</i></b> for their insight, knowledge and advice.<br />
<br />
<div class="separator" style="margin-left: 1em; margin-right: 1em; text-align: center;">
<a href="http://www.packtpub.com/oracle-jdeveloper-11gR2-to-build-adf-applications-cookbook/book">
<img border="0" height="320" src="https://4.bp.blogspot.com/-Bk30Uki1328/TyBZPprXPAI/AAAAAAAAA4k/fqruGefMXt8/s320/book.png" width="231" />
</a>
</div>
<div class="separator" style="clear: both; text-align: left;">
For further details about the book click <a href="http://www.packtpub.com/oracle-jdeveloper-11gR2-to-build-adf-applications-cookbook/book">here</a>. <span style="font-size: x-small;"><i><u><br /></u></i></span></div>
<br />
<div class="separator" style="clear: both; text-align: left;">
<span style="font-size: small;">Here are some peer references/reviews of the book from the blog sphere:</span></div>
<ul style="text-align: left;">
<li><span style="font-size: x-small;"><a href="https://blogs.oracle.com/shay/entry/new_adf_book_oracle_jdeveloper">https://blogs.oracle.com/shay/entry/new_adf_book_oracle_jdeveloper</a> </span></li>
<li><span style="font-size: x-small;"><a href="http://monkeyonoracle.blogspot.com/2012/02/preparing-to-work-with-adf.html">http://monkeyonoracle.blogspot.com/2012/02/preparing-to-work-with-adf.html</a></span></li>
<li><span style="font-size: x-small;"><a href="http://antonis-antoniou.blogspot.com/2012/03/new-adf-book-oracle-jdeveloper-11gr2.html">http://antonis-antoniou.blogspot.com/2012/03/new-adf-book-oracle-jdeveloper-11gr2.html</a> </span></li>
<li><span style="font-size: x-small;"><a href="http://www.adftips.com/2012/03/oracle-jdeveloper-11gr2-cookbook-new.html">http://www.adftips.com/2012/03/oracle-jdeveloper-11gr2-cookbook-new.html</a> </span></li>
<li><span style="font-size: x-small;"><a href="http://nickaiva.blogspot.com/2011/12/preview-of-oracle-jdeveloper-11gr2.html">http://nickaiva.blogspot.com/2011/12/preview-of-oracle-jdeveloper-11gr2.html</a></span></li>
<li><span style="font-size: x-small;"><a href="https://blogs.oracle.com/grantronald/entry/book_to_review_oracle_jdeveloper11gr2">https://blogs.oracle.com/grantronald/entry/book_to_review_oracle_jdeveloper11gr2</a></span></li>
<li><span style="font-size: x-small;"><a href="https://blogs.oracle.com/jdeveloperpm/entry/new_adf_book_oracle_jdeveloper">https://blogs.oracle.com/jdeveloperpm/entry/new_adf_book_oracle_jdeveloper</a></span></li>
<li><span style="font-size: x-small;"><a href="http://www.oraclemagazine-digital.com/oraclemagazine_twitter/20120304?pg=31#pg31">http://www.oraclemagazine-digital.com/oraclemagazine_twitter/20120304?pg=31#pg31</a></span></li>
<li><span style="font-size: x-small;"><a href="https://forums.oracle.com/forums/thread.jspa?threadID=2351960">https://forums.oracle.com/forums/thread.jspa?threadID=2351960</a></span></li>
<li><span style="font-size: x-small;"><a href="https://blogs.oracle.com/onesizedoesntfitall/entry/oracle_jdeveloper_11gr2_cookbook_book">https://blogs.oracle.com/onesizedoesntfitall/entry/oracle_jdeveloper_11gr2_cookbook_book</a> </span></li>
<li><span style="font-size: x-small;"><a href="http://serafeimk.blogspot.com/2012/04/adf-11g-oracle-jdeveloper-11gr2.html">http://serafeimk.blogspot.com/2012/04/adf-11g-oracle-jdeveloper-11gr2.html</a> </span></li>
<li><span style="font-size: x-small;"><a href="http://xmlandmore.blogspot.com/2012/04/book-review-oracle-jdeveloper-11gr2.html">http://xmlandmore.blogspot.com/2012/04/book-review-oracle-jdeveloper-11gr2.html</a> </span></li>
<li><span style="font-size: x-small;"><a href="http://www.amazon.com/Oracle-JDeveloper-11gR2-Cookbook-ebook/product-reviews/B00719PC60/ref=dp_top_cm_cr_acr_txt?ie=UTF8&showViewpoints=1">http://www.amazon.com/Oracle-JDeveloper-11gR2-Cookbook-ebook/product-reviews/B00719PC60/ref=dp_top_cm_cr_acr_txt?ie=UTF8&showViewpoints=1</a> </span></li>
</ul>
</div>
Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com2tag:blogger.com,1999:blog-2827440252127411773.post-22218785629376278672012-02-27T05:29:00.000+02:002012-02-27T05:29:13.345+02:00Bit #39 - Retrieving the current session id at the ADFBC layer<div dir="ltr" style="text-align: left;" trbidi="on">
If you need to retrieve the current session identifier at the ADF Business Components layer, use the <b><i>getId()</i></b> method defined in the <b><i>oracle.jbo.SessionContext</i></b> interface. You can get the <b><i>oracle.jbo.SessionContext</i></b> interface by calling <b><i>getCurrentSession()</i></b> which is defined in the <b><i>oracle.jbo.SessionContextManager</i></b> interface. So, how do you get the <b><i>oracle.jbo.SessionContextManager</i></b> interface? Call any of the <b><i>findOrCreateSessionContextManager()</i></b> or <b><i>getSessionContextManager()</i></b> static methods in <b><i>SessionImpl</i></b>. Finally, you may asking why you might need the current session id at the ADFBC layer? In my case, I had to log it in the database as part of a generic session audit process during DML. Here is an example:<br />
<br />
<span style="font-size: large;"><b>Example:</b></span><br />
<br />
<i>// in the context of ADFBC</i><br />
<i>SessionImpl.findOrCreateSessionContextManager().getCurrentSession().getId()</i><br />
<br />
<span style="font-size: large;"><b>Notes:</b></span><br />
<ul style="text-align: left;">
</ul>
<u>Note #1</u>: The <b><i>oracle.jbo.SessionContext</i></b> interface also provides a method called <b><i>getType()</i></b> that returns the session type. It can be any of the following: <i><b>TYPE_HTTP_SESSION</b></i>, <b><i>TYPE_EJB_SESSION</i></b> or <b><i>TYPE_THREAD_SESSION</i></b>.<br />
<br />
<u>Note #2</u>: Here are some example session ids retrieved when calling <b><i>oracle.jbo.SessionContext.getId()</i></b>:<br />
<ul style="text-align: left;">
<li>HTTP session (original session):<span style="font-size: xx-small;"> FGHpPKhfwJSQ5hkKChGnNyhCH10sVrvyGGL44GSz1vCpyZQbkFJX!2144650654!1330307487797_wsc30xy1y_<span style="font-size: large;"><b>1</b></span></span></li>
<li>HTTP session (same session, another browser tab): <span style="font-size: xx-small;">FGHpPKhfwJSQ5hkKChGnNyhCH10sVrvyGGL44GSz1vCpyZQbkFJX!2144650654!1330307487797_wsc30xy1y_<span style="font-size: large;"><b>5</b></span></span></li>
<li>ADF Model Tester:<span style="font-size: xx-small;"> d7a748c1-0343-4f50-91d6-171cf9f8c5e5__root_frame_</span></li>
<li>ADF Model Tester (after <b><i>File </i></b>| <b><i>Reload application</i></b>): <span style="font-size: xx-small;">d7a748c1-0343-4f50-91d6-171cf9f8c5e5__root_frame_</span></li>
</ul>
<span style="font-size: large;"><b>Context:</b></span><br />
<br />
<span style="font-size: xx-small;"><span style="font-size: small;">ADF Business Components </span> </span><br />
<ol>
</ol>
</div>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com0tag:blogger.com,1999:blog-2827440252127411773.post-69919091364264232012-01-11T23:13:00.001+02:002012-01-11T23:13:56.736+02:00Bit #38 - Creating a custom ADF Faces client-side converter<div dir="ltr" style="text-align: left;" trbidi="on">
You can create a custom ADF Faces client-side converter by ensuring that your converter class implements the <b><i>org.apache.myfaces.trinidad.convert.ClientConverter</i></b> interface. This is done in addition to implementing the <i>javax.faces.convert.Converter</i> interface, which implements the custom converter on the server. To implement the <b><i>ClientConverter</i></b> interface you need to provide implementation for the <b><i>getClientConversion()</i></b> and <b><i>getClientScript()</i></b> methods. The <b><i>getClientConversion()</i></b> implementation should return the JavaScript constructor of the client converter. The <b><i>getClientScript()</i></b> implementation on the other hand should return the actual JavaScript code that implements the client converter.<br />
<br />
<span style="font-size: large;"><b>Example:</b></span><br />
<br />
public class CustomConverter implements javax.faces.convert.Converter,<br />
<b><i> org.apache.myfaces.trinidad.convert.ClientConverter</i></b> {<br />
<br />
// implement the <i>javax.faces.convert.Converter</i> interface for server-side conversion<br />
<br />
// implement the<i> org.apache.myfaces.trinidad.convert.ClientConverter</i> interface for<br />
// client-side conversion<br />
<br />
// return the JavaScript client converter <br />
public String <b><i>getClientConversion</i></b>(FacesContext context, UIComponent component) {<br />
return "new CustomConverter()";<br />
}<br />
<br />
// return the actual client converter JavaScript code<br />
public String <b><i>getClientScript</i></b>(FacesContext context, UIComponent component) {<br />
return null;<br />
}<br />
}<br />
<br />
For a complete implementation of an ADF Faces client converter take a look at this reference from an older Oracle documentation: <a href="http://docs.oracle.com/cd/B25221_05/web.1013/e18745/devguide/clientValidation.html#Client-side%20Validators">http://docs.oracle.com/cd/B25221_05/web.1013/e18745/devguide/clientValidation.html#Client-side%20Validators</a>. Unfortunately, this example is not part of the latest documentation.<br />
<br />
<span style="font-size: large;"><b>Context:</b></span><br />
<br />
ADF Faces</div>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com0tag:blogger.com,1999:blog-2827440252127411773.post-72484049517913068782012-01-08T11:34:00.004+02:002012-01-09T00:08:26.104+02:00Bit #37 - Preventing client events from propagating to the server<div dir="ltr" style="text-align: left;" trbidi="on">
ADF Faces client events, i.e. events delivered and implemented on the browser using JavaScript, by default do propagate to the server. There might be cases however that you don't want this default propagation. For instance, consider an <i>af:commandButton</i> component that defines a <i>clientListener</i> but has no <i>actionListener</i> defined. In this case propagating the client event to the server would be unnecessary. To stop the client event from propagating to the server use the <b><i>cancel()</i></b> method of the event class. Event classes are subclasses of the <b><i>AdfBaseEvent</i></b> class.<br />
<br />
You listen to client events by using the <i>af:clientListener</i> component to call a JavaScript method in response to a client event. The <i>af:clientListener</i> component is used as a child of the ADF Faces component that generates the event.<br />
<br />
Finally, note that in order to be able to cancel an event from propagating to the server, the event must be cancelable. You can determine whether an event is cancelable or not by calling the event <b><i>isCancelable()</i></b> method. This method returns <i>true</i> if event propagation can be canceled.<br />
<br />
<span style="font-size: large;"><b>Example:</b></span><br />
<br />
<i>function customClientListener(event)<br />{</i><br />
<i> // cancel event propagation to the server<br /> if (</i><i><b>event.isCancelable()</b>) {</i><br />
<i> </i><b><i>event.cancel();</i></b><br />
<i> } </i><br />
<br />
<i> // do client event processing </i><br />
<i>}</i><br />
<i><br /></i><br />
<span style="font-size: large;"><b>Context:</b></span><br />
<br />
ADF Faces</div>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com1tag:blogger.com,1999:blog-2827440252127411773.post-11258295912239418452012-01-07T12:25:00.000+02:002012-01-07T12:27:33.626+02:00Bit #36 - Preventing client UI input during server event processing<div dir="ltr" style="text-align: left;" trbidi="on">
To prevent any client UI input during the server processing of an event use the <b><i>AdfCustomEvent preventUserInput()</i></b> method in your JavaScript client listener. Calling this method prior to queuing the event will display a glass pane covering the browser window and will prevent further user input until the server event processing is complete. To use this method in a client listener first construct an <b><i>AdfCustomEvent</i></b> and and then call <b><i>preventUserInput()</i></b> on it before calling <b><i>queue()</i></b> to propagate the event to the server. Add custom client and server listeners using the <i>af:clientListener</i> and <i>af:serverListener</i> ADF Faces components as children of the component generating the client event.<br />
<br />
To make this a generic implementation, think about providing your own custom <b><i>queue()</i></b> JavaScript method that accepts among others a boolean indicator called <i>preventInput </i>to indicate whether client UI input is to be prevented or not during the server event processing. For instance: <i>queue(source,serverListener,params,immediate,ppr,<b>preventInput</b>)</i>.<br />
<br />
Here is an example client listener demonstrating how to use <b><i>preventUserInput()</i></b>:<br />
<br />
<span style="font-size: large;"><b>Example:</b></span><br />
<br />
<i>function customClientListener(event)<br />{</i><br />
<i> // get the event source<br /> var source = event.getSource();</i><br />
<i> </i><br />
<i> // create the event<br /> var customEvent = new <b>AdfCustomEvent</b></i><i>(source, "customServerListener", {}, true);</i><br />
<i> // call preventUserInput() to block UI input<br /> customEvent.<b>preventUserInput()</b>;</i><br />
<i> // send the event to the server<br /> customEvent.queue(true);<br />}</i><br />
<br />
<span style="font-size: large;"><b>Context:</b></span><br />
<br />
ADF Faces</div>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com0tag:blogger.com,1999:blog-2827440252127411773.post-10222964140518511142012-01-06T14:36:00.000+02:002012-01-07T12:25:46.106+02:00Bit #35 - Using client behavior tags with ADF Faces<div dir="ltr" style="text-align: left;" trbidi="on">
<i>Partial page rendering (PPR)</i> is supported in ADF Faces through the use of the <b><i>partialTrigers</i><i> </i></b>attribute and the <i>AdfFacesContext <b>addPartialTarget()</b></i> method (see <a href="http://adfcodebits.blogspot.com/2010/04/bit-10-selectively-enabling-partial.html">Bit #10 - Selectively enabling Partial Page Rendering programmatically</a>). <i>PPR</i> however can also be achieved in ADF Faces applications using the <i>JSF 2.0 client behavior API</i> and the use of client behavior tags such as the <b><i>f:ajax</i></b> tag. This tag is added as a child tag to an ADF Faces component and allow for the execution of <i>PPR</i> in response to a component client event. The specifications of the <b><i>f:ajax</i></b> tag is shown below:<br />
<br />
<b><i><f:ajax event="..." render="..." execute="..." listener="..." ...</i></b><br />
<br />
<b><i>event</i></b> is a string indicating on which events an Ajax request will be fired,<br />
<b><i>render</i></b> is a string indicating the identifiers of the components to render<br />
<b><i>execute </i></b>is a string indicating the identifiers of the components to be processed on the server<br />
<b><i>listener</i></b> indicates a method to invoke during the Ajax request<br />
<br />
Complete documentation on the <b><i>f:ajax</i></b> tag can be found here: <a href="http://javaserverfaces.java.net/nonav/docs/2.0/pdldocs/facelets/f/ajax.html">http://javaserverfaces.java.net/nonav/docs/2.0/pdldocs/facelets/f/ajax.html</a>. <br />
<br />
Here is an example of how to use the <b><i>f:ajax</i></b> tag to achieve <i>PPR</i> of an <i>af:outputText</i> based on a value change event originating from an <i>af:inputText</i> component:<br />
<br />
<span style="font-size: large;"><b>Example:</b></span><br />
<br />
<i><af:inputText ...<br /> <b><f:ajax name="change" render="ot" execute="@this" /></b><br /></af:inputText><br /><af:outputText id="ot" ... </i><br />
<br />
The <b><i>@this</i></b> value for the <b><i>execute</i></b> attribute indicates that only the component that triggered the Ajax request will be processed on the server.<br />
<br />
<span style="font-size: large;"><b>Context:</b></span><br />
<br />
ADF Faces</div>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com0tag:blogger.com,1999:blog-2827440252127411773.post-87758297278577046422012-01-02T13:29:00.000+02:002012-01-07T12:25:59.642+02:00Bit #34 - Using JavaScript partitioning<div dir="ltr" style="text-align: left;" trbidi="on">
JavaScript partitioning is the way ADF Faces partitions and delivers
JavaScript code to the client. ADF Faces groups its ADF Faces components
JavaScript code into so called <i>features </i>and then packages and delivers related features in so called JavaScript <i>partitions</i>. There are two files involved in the delivery of JavaScript partitions to the client: <b><i>adf-js-features.xml</i></b> and <b><i>adf-js-partitions.xml</i></b>.
The first lists the JavaScript classes that make up a feature and its
relationships with other features. The second groups the JavaScript
features in partitions.<br />
<br />
Of course JavaScript can also
be delivered to the client by directly adding the JavaScript code to the
page or referencing a JavaScript library in the page. Bundling all of
your JavaScript code in a few JavaScript Libraries will result in longer
download time, while adding JavaScript directly to each page will
result in more roundtrips to the server. This is why partitioning is
used, as an alternative to specifically tune and customize the
JavaScript requirements on a per-application basis.<br />
<br />
Here are some examples of the <b><i>adf-js-features.xml</i></b> and <b><i>adf-js-partitions.xml</i></b> JavaScript partitioning files:<br />
<br />
<span style="font-size: large;"><b>Example:</b></span><br />
<br />
<b><i>META-INF/adf-js-features.xml</i></b><br />
<br />
<i><?xml version="1.0" encoding="utf-8" ?><br /><adf-js-features xmlns="http://xmlns.oracle.com/adf/faces/feature"><b><br /></b> <<b>features </b>xmlns="http://xmlns.oracle.com/adf/faces/feature"><br /> <<b>feature</b>><br /> <<b>feature-name</b>>CustomComponent</feature-name><br /> <<b>feature-class</b>>js/custom/CustomComponent.js</feature-class><br /> <feature-class>js/custom/CustomComponentEvent.js</feature-class><br /> <<b>feature-dependency</b>>AdfRichPopup</feature-dependency><br /> </feature></i><br />
<i> </features></i><br />
<i></adf-js-features> </i> <br />
<br />
<br />
<b><i>WEB-INF/adf-js-partitions.xml</i></b><br />
<br />
<i><?xml version="1.0" encoding="utf-8" ?><br /> <<b>partitions </b>xmlns="http://xmlns.oracle.com/adf/faces/partition"><br /> <<b>partition</b>><br /> <<b>partition-name</b>>CustomPartition</partition-name><br /> <<b>feature</b>>CustomComponent</feature><br /> <feature>CustomCommon</feature><br />
<feature>CustomUtils</feature><br /> </partition></i><br />
<i> </partitions></i><br />
<br />
<span style="font-size: large;"><b>Context:</b></span><br />
<br />
ADF Faces</div>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com1tag:blogger.com,1999:blog-2827440252127411773.post-6336887800519846342011-12-30T19:43:00.001+02:002012-01-07T12:26:11.307+02:00Bit #33 - Using custom client attributes<div dir="ltr" style="text-align: left;" trbidi="on">
To use a custom client attribute for an ADF Faces component use an <b><i>af:clientAttribute</i></b> component as a child component of that component and specify the <b><i>name </i></b>and <b><i>value</i></b> of the custom attribute. Then use the JavaScript <i><b>AdfUIComponent.getProperty()</b></i> method to retrieve the property value at runtime on the client.<br />
<br />
<u>Note</u> that custom client attributes <b><u>are not</u></b> delivered to the server automatically. To do so you must create a custom event from the client to the server using an <i>af:serverListener</i> component and queue the event by calling <i>AdfCustomEvent.queue()</i>.<br />
<br />
Here is an example of adding a custom client attribute to an <i>af:inputText</i> component. We have added an <i>af:clientListener</i> to demonstrate calling the <i><b>AdfUIComponent.getProperty()</b></i> method.<br />
<br />
<span style="font-size: large;"><b>Example:</b></span><br />
<br />
<i> <af:inputText label="Label 1" id="it1"><br /> <<b>af:clientAttribute name="customAttribute" value="Hello, world"/></b><br /> <af:clientListener type="valueChange" method="onInputTextValueChange"/><br /> </af:inputText></i><br />
<br />
....<br />
<i> <af:resource type="javascript"><br /> function onInputTextValueChange(event) {<br /> var inputText = event.getSource();<br /> // retrieve and display the custom client attribute<br /> alert(inputText.<b>getProperty("customAttribute")</b>);<br /> }<br /> </af:resource></i><br />
<br />
<br />
<span style="font-size: large;"><b>Context:</b></span><br />
<br />
ADF Faces</div>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com0tag:blogger.com,1999:blog-2827440252127411773.post-60966272160805553512011-12-28T13:31:00.001+02:002012-01-07T12:26:20.712+02:00Bit #32 - Locating a component on the client<div dir="ltr" style="text-align: left;" trbidi="on">
To locate a component on the client side of an ADF Faces application use any of the <i><b>AdfUIComponent.findComponent()</b></i> or <i><b>AdfPage.PAGE.findComponentByAbsoluteId()</b></i> methods. Both of these methods accept the component's identifier. The difference between the two is that while <i><b>AdfUIComponent.findComponent()</b></i> accepts a relative expression representing the component identifier, <i><b>AdfPage.PAGE.findComponentByAbsoluteId()</b></i> expects an absolute expression for the component's identifier. Absolute expressions use a fully qualified client identifier with a leading separator character, for example <i>:container1:container2:componentId</i>.<br />
<br />
To guaranty that a client side instance of the component exists, ensure that you have set the component's <i><b>clientComponent </b></i>property to <i>true</i>. Alternatively, you can add a <i><b>clientListener </b></i>to the component instead.
<br />
<br />
Finally, <u>do not use</u> the <b><i>AdfPage.PAGE.findComponent()</i></b> method because its implementation may change from release to release.<br />
<br />
<span style="font-size: large;"><b>Example:</b></span><br />
<br />
<i>function exampleFunc(actionEvent)
{ </i><br />
<i> var someComponent=actionEvent.getSource();</i><br />
<i> // use findComponent() to locate a component relative to 'someComponent'</i><br />
<i> var someOtherComponent=someComponent.<b>findComponent</b>("componentId");</i><br />
<i>
someOtherComponent.setValue("Hello") </i><br />
<i>} </i><br />
<br />
<span style="font-size: large;"><b>Context:</b></span><br />
<br />
ADF Faces</div>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com1tag:blogger.com,1999:blog-2827440252127411773.post-12373882146500972332011-07-04T11:13:00.000+03:002011-07-04T11:13:03.425+03:00Bit #31 - Making an Entity object read-only<div dir="ltr" style="text-align: left;" trbidi="on">There are a few different ways to make an Entity object read-only, both declaratively in JDeveloper or programmatically via the ADF Business Components API. One that is suggested in OTN thread <a href="http://forums.oracle.com/forums/thread.jspa?threadID=2247578&tstart=0">http://forums.oracle.com/forums/thread.jspa?threadID=2247578&tstart=0</a> is to change in the Entity's <i>General</i> section the Entity's <i><b>Updatable</b></i> property from <i><b>true </b></i>(the default) to <i><b>false</b></i>. This property can be found under the <i>Type </i>section in the <i>Property Inspector</i>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-_gZMjEqrV8k/ThFxB5X8oQI/AAAAAAAAA4c/eC6yFvmt03Q/s1600/CodeBits.31.1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="261" src="http://1.bp.blogspot.com/-_gZMjEqrV8k/ThFxB5X8oQI/AAAAAAAAA4c/eC6yFvmt03Q/s320/CodeBits.31.1.PNG" width="320" /></a></div><br />
<div class="separator" style="clear: both; text-align: center;"></div>By changing it to <i><b>false</b></i>, the Entity will not be updatable for all Entity-based View objects that use it. Note however that JDeveloper will still show the Entity reference as being <i>Updatable </i>in the View object <i>Entity Objects</i> page. This seems to be a bug in JDeveloper.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-u7u51Zxcl8c/ThF0kLz-I2I/AAAAAAAAA4g/OxMEXM_YwC4/s1600/CodeBits.31.2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="198" src="http://4.bp.blogspot.com/-u7u51Zxcl8c/ThF0kLz-I2I/AAAAAAAAA4g/OxMEXM_YwC4/s320/CodeBits.31.2.PNG" width="320" /></a></div>Some of the other ways to make the Entity read only would be to uncheck the <b><i>Updatable </i></b>checkbox for each View object that uses the Entity object (in the <i>Entity Objects</i> section), to use the <b><i>isAttributeUpdatable()</i></b> API to return false for all attributes or even at the attribute level to set each attribute's <i>Updatable</i> property to <i><b>Never</b></i>. <br />
<br />
<span style="font-size: large;"><b>Context:</b></span><br />
Entity Objects</div>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com0tag:blogger.com,1999:blog-2827440252127411773.post-592089589705812412011-05-06T10:11:00.005+03:002011-05-06T12:48:57.683+03:00Bit #30 - Displaying the current row on an af:table<div dir="ltr" style="text-align: left;" trbidi="on">You can display the current record number as you navigate an <i>af:table</i> by using certain information available on the table's iterator binding, namely the <b><i>currentRowIndexInRange</i></b> and <i><b>rangeStart</b></i> attributes. The current row can be calculated by the following EL expression: <b><i>#{bindings.Iterator.rangeStart+bindings.Iterator.currentRowIndexInRange+1}</i></b>, where <i>Iterator</i> is the table's bound iterator identifier. We add one because the row index is 0-based. You will need to surround the <i>af:table</i> with an <i>af:panelCollection </i>and use one of its facets - I suggest using the <i>secondaryToolbar</i> facet - to add an <i>af:toolbar</i> with an <i>af:outputText</i> inside it. For the current record count to be updated as you navigate the table, you will need to setup a <i>partialTrigger</i> on the <i>af:outputText</i> to the <i>af:table</i>. The example below shows this implementation.<br />
<br />
<span style="font-size: large;"><b>Example:</b></span><br />
<br />
<i><<b>af:panelcollection</b> ... </i><i>></i><br />
<i><<b>af:table</b> id="tbl1" ... ><br />
</af:table></i><br />
<i> <f:facet name="<b>secondaryToolbar</b>"><br />
<af:toolbar id="t1"><br />
<af:group id="g1"><br />
<af:outputtext id="ot24" value="#{bindings.Employees1Iterator.<b>rangeStart</b>+bindings.Employees1Iterator.<b>currentRowIndexInRange</b>+1}/#{bindings.Employees1Iterator.estimatedRowCount} records"><br />
visible="#{bindings.Employees1Iterator.currentRow ne null}"<br />
<b>partialTriggers="tbl1</b> ::qryId1"/><br />
</af:group</i><i>></i><br />
<i> </i><i><</i><i>/af:toolbar</i><i>></i><br />
<i> </i><i><</i><i>/f:facet</i><i>></i><br />
<i> </af:panelcollection></i><br />
<br />
Here is what the output looks like:<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/-em_l5Xh1G-8/TcOaxmt_P0I/AAAAAAAAA3k/wT5sCs2Ibjk/s1600/CodeBits.30.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="165" src="http://2.bp.blogspot.com/-em_l5Xh1G-8/TcOaxmt_P0I/AAAAAAAAA3k/wT5sCs2Ibjk/s320/CodeBits.30.PNG" width="320" /></a></div><br />
<span style="font-size: large;"><b>Context:</b></span><br />
<br />
JSF page<br />
<br />
</div>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com0tag:blogger.com,1999:blog-2827440252127411773.post-33158030975410130202011-03-24T16:55:00.001+02:002011-03-24T17:00:12.849+02:00Bit #29 - Dynamically configure ADF trace logs in WebLogic<div dir="ltr" style="text-align: left;" trbidi="on">ADF-specific logging can be dynamically configured in WebLogic via the <i><b>wlst </b></i>script. Ensure that you run the <i><b>wlst </b></i>script that is located in oracle common directory (and not the one in the WebLogic server home). Then connect to the administration server and use the <i><b>setLogLevel()</b></i> command to change the appropriate logger's level. To configure Business Components logs specify <i><b>oracle.jbo</b></i> as the logger. Similarly to configure the ADF Controller and ADF Faces logs use the <i><b>oracle.adf.controller</b></i> and <i><b>oracle.adf.faces</b></i> loggers respectively. For the example below, the ADF application is deployed on <i>ManagedServer1</i>. As mentioned, these changes to the logging configuration can be done at run-time without the need to re-start the server.<br />
<br />
<br />
<span style="font-size: large;"><b>Example:</b></span><br />
<br />
<i>wlst</i><br />
<i>connect('weblogic','weblogic1', 't3://192.168.5.134:7001')</i><br />
<i>setLogLevel(target='ManagedServer1', logger='<b>oracle.jbo</b>', level='FINEST')</i><br />
<br />
<br />
<span style="font-size: large;"><b>Context:</b></span><br />
<br />
ADF BC<br />
ADF Faces<br />
ADF Controller<br />
<br />
<br />
<span style="font-size: large;"><b>References:</b></span><br />
<br />
<a href="http://jdeveloperfaq.blogspot.com/2011/03/faq-33-how-to-configure-adf-diagnostics.html">http://jdeveloperfaq.blogspot.com/2011/03/faq-33-how-to-configure-adf-diagnostics.html</a><br />
<br />
</div>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com0tag:blogger.com,1999:blog-2827440252127411773.post-64273643424517061162010-12-14T17:46:00.003+02:002010-12-14T17:59:10.150+02:00Bit #28 - Using findDefObject() to load a BC definition object from its metadata XMLIf you ever thought of parsing any of the ADF Business Components (BC) metadata XML files for the sake of extracting various metadata information, you might want to think twice. The ADF framework offers higher level APIs to do this routine job. Case in point: take a look at the <b><i>findDefObject()</i></b> methods available in a number of definition classes such as <i><b>oracle.jbo.server.EntityDefImpl</b></i> and <b><i>oracle.jbo.server.ViewDefImpl</i></b> for example. By calling this method, the metadata is parsed and loaded for you into the corresponding <b><i>EntityDefImpl </i></b>or <b><i>ViewDefImpl</i></b>. Neat! Then extracting metadata information is as easy as calling the corresponding methods. For example, to get all the attributes defined for a View Object, you can call V<i><b>iewDefImpl.getAttributeDefs()</b></i>. When calling <i><b>findDefObject()</b></i> ensure that the location of your BC definition files is listed in the class path. Here is an example:<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Example:</span></b><br />
<br />
<i>import oracle.jbo.AttributeDef;</i><br />
<i>import oracle.jbo.server.AttributeDefImpl;</i><br />
<i>import oracle.jbo.server.EntityDefImpl;</i><br />
<i>import oracle.jbo.server.ViewDefImpl;</i><br />
<div><i><br />
</i></div><br />
<i>public class ADFMetaDataTester {</i><br />
<br />
<i> public static void main(String[] args) {</i><br />
<br />
<i> // load EO definition from Employee.xml</i><br />
<i> EntityDefImpl eoDef = <b>EntityDefImpl.findDefObject</b>("Employee");</i><br />
<i> // now, you can for example get the unique keys defined by the EO</i><br />
<i> AttributeDefImpl[] uniqueKeys = eoDef.getUniqueKeys();</i><br />
<br />
<i> // load VO definition from EmployeesVO.xml</i><br />
<i> ViewDefImpl voDef = <b>ViewDefImpl.findDefObject</b>("EmployeesVO");</i><br />
<i> // get the VO attributes</i><br />
<i> AttributeDef[] attributes = voDef.getAttributeDefs();</i><br />
<i> }</i><br />
<i>}</i><br />
<div><br />
</div><br />
<b><span class="Apple-style-span" style="font-size: large;">Context:</span></b><br />
<br />
ADF Business Components (BC)Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com1tag:blogger.com,1999:blog-2827440252127411773.post-19717309613318156012010-11-24T16:03:00.002+02:002010-11-24T16:20:32.471+02:00Bit #27 - Setting a View Object attribute's Queryable propertyExpanding on <a href="http://adfcodebits.blogspot.com/2010/11/bit-26-overriding-getattributedef-to.html">Bit #26 - Overriding getAttributeDef() to conditionally set an attribute property</a>, you can set a View Object's attribute <i>queryable </i>property simply by calling <i><b>setQueriable()</b></i> on its <i><b>ViewAttributeDefImpl</b></i>. As explained in Bit #26, you can get the <i><b>AttributeDef</b></i><b> </b>attribute definition by calling <i><b>getAttributeDef()</b></i> and passing the attribute index as a parameter. In order to call any of the attribute <i>set...()</i> methods, you will have to cast the <i><b>AttributeDef</b></i> interface to an <i><b>ViewAttributeDefImpl</b></i><b> </b>implementation. By the way, did you know that by setting an attribute's <i>queryable </i>property will show or hide a <i>View Criteria Item</i> (i.e. the criterion) based on the attribute on the <i>af:query</i> dialog? Another way to hide the criterion was outlined in <a href="http://adfcodebits.blogspot.com/2010/11/bit-25-hiding-view-criteria-item-based.html">Bit #25 - Hiding a View Criteria item based on some condition</a>. It will also show or hide the attribute from the <i>Add Fields</i> drop-down in the <i>Advanced</i> mode of <i>af:query</i>. One last thing: check-out the plethora of <i>set...()</i> methods available in the <i><b>ViewAttributeDefImpl.</b></i><b> </b>As you may have guessed it, pretty much everything that is available declaratively on the <i>Edit Attribute</i> dialog, can be set (or reset) dynamically in your code based on some business condition. For a complete use case, check out the reference listed below.<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Example:</span></b><br />
<br />
<i> /**<br />
* Helper to set an attribute's queriable property.<br />
* Example:<br />
* setQueriable(ViewRowImpl.SOMEFIELDINDEX, something.equals(somethingElse));<br />
*<br />
* @param attribIndex the attribute index<br />
* @param condition the condition (true/false)<br />
*/<br />
protected void setQueriable(int attribIndex, boolean condition) {<br />
// set the attribute queryable as needed<br />
AttributeDef def = super.getAttributeDef(attribIndex);<br />
boolean queryable = condition;<br />
<br />
// set/reset queriable only if needed<br />
if (def != null && def.isQueriable() != queryable) {<br />
ViewAttributeDefImpl attributeDef = (ViewAttributeDefImpl)def;<br />
attributeDef.setQueriable(queryable);<br />
}<br />
}<br />
</i><br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Context:</span></b><br />
<br />
View Object Implementation Class<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">References:</span></b><br />
<br />
<a href="http://dstas.blogspot.com/2010/03/set-queryable-property-on-attribute.html">http://dstas.blogspot.com/2010/03/set-queryable-property-on-attribute.html</a>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com0tag:blogger.com,1999:blog-2827440252127411773.post-62504827964227322112010-11-23T09:47:00.001+02:002010-11-23T09:51:40.730+02:00Bit #26 - Overriding getAttributeDef() to conditionally set an attribute propertyYou can override <i>ViewObjectImpl</i>'s <i><b>getAttributeDef()</b></i> method to update an attribute setting, control hint or a custom property. <i><b>getAttributeDef()</b></i> is called by the framework each time the attribute's definition needs to be accessed, for example prior to opening an <i>af:query</i> search dialog. In such a case, this may be the ideal place to set a conditional queryable property for example. The argument that is passed to the method indicates the index of the attribute being accessed. You modify the attribute definition by calling <i><b>super.getAttributeDef()</b></i> to get the <i><b>AttributeDef</b></i> and then call any of its <i>set...()</i> methods. Here is an example:<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Example:</span></b><br />
<br />
<i> @Override<br />
public AttributeDef getAttributeDef(int attribIndex) {<br />
<span class="Apple-style-span" style="font-style: normal;"><i> // check for some specific attribute</i></span></i><br />
<i> if (attribIndex == SOME_ATTRIBUTE_INDEX) {<br />
//get the attribute's definition<br />
AttributeDef def = super.getAttributeDef(attribIndex);<br />
<br />
// conditionally update some attribute value</i><br />
<i> // if (someCondition) {<br />
//((ViewAttributeDefImpl)def).set...()</i><br />
<i> //}<br />
<br />
return def;<br />
}<br />
<br />
return super.getAttributeDef(attribIndex);<br />
}<br />
</i><br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Context:</span></b><br />
<br />
View Object Implementation ClassNickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com1tag:blogger.com,1999:blog-2827440252127411773.post-53987228624218478072010-11-22T15:13:00.000+02:002010-11-22T15:13:59.461+02:00Bit #25 - Hiding a View Criteria item based on some conditionYou can hide or show a View Criteria item (i.e. a criterion), based on some business logic condition by calling <i><b>setProperty()</b></i> on an <i>oracle.jbo.ViewCriteriaItem</i>. The method accepts a <i>ViewCriteriaItemHints </i>parameter indicating the view criteria item property to set - in this case <i><b>CRITERIA_RENDERED_MODE</b></i> - and a second <i>ViewCriteriaItemHints </i>parameter indicating the property value - in this case any of the <i>CRITERIA_RENDERED_MODE_BOTH</i>, <i>CRITERIA_RENDERED_MODE_BASIC</i>, <i>CRITERIA_RENDERED_MODE_ADVANCED</i>, <i>CRITERIA_RENDERED_MODE_NEVER</i>, <i>CRITERIA_RENDERED_MODE_DEFAULT</i>. To hide or show a criterion, you will have to look for it by iterating through all the criteria rows and all the criteria items for each row. Once found, call <i><b>setProperty()</b></i> to set its render mode. Here is an example helper method that illustrates this case.<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Example:</span></b><br />
<br />
<i> /**<br />
* Hides a view criterion.<br />
* Example: The following will hide the SourcePolicyNbr criterio if the condition<br />
* is true. If the condition is false, it will show the criterio in BOTH basic and<br />
* advanced.<br />
* <br />
* hideCriteriaItem("SomeCriteria", "SomeCriteriaItem",<br />
* someCondition==true, ViewCriteriaItemHints.CRITERIA_RENDERED_MODE_BOTH);<br />
*<br />
*<br />
* @param viewCriteriaName the view criteria name<br />
* @param criteriaItemName the criterio name<br />
* @param condition the HIDE condition<br />
* @param showHint the SHOW hint<br />
*/<br />
protected void hideCriteriaItem(String viewCriteriaName,<br />
String criteriaItemName, boolean condition,<br />
String showHint) {<br />
if (viewCriteriaName != null) {<br />
ViewCriteria v = this.getViewCriteria(viewCriteriaName);<br />
if (v != null) {<br />
boolean found = false;<br />
while (v.hasNext() && !found) {<br />
ViewCriteriaRow vcr = (ViewCriteriaRow)v.next();<br />
if (vcr != null) {<br />
ViewCriteriaItem[] vcis = vcr.getCriteriaItemArray();<br />
if (vcis != null && vcis.length > 0) {<br />
for (int j = 0; j < vcis.length && !found; j++) {<br />
ViewCriteriaItem vci = vcis[j];<br />
if (vci != null && criteriaItemName != null &&<br />
criteriaItemName.equals(vci.getName())) {<br />
found = true;<br />
vci.<b>setProperty</b>(ViewCriteriaItemHints.CRITERIA_RENDERED_MODE,<br />
condition ?<br />
ViewCriteriaItemHints.CRITERIA_RENDERED_MODE_NEVER :<br />
showHint);<br />
v.saveState();<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br />
}<br />
</i><br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Context:</span></b><br />
<br />
View Object Implementation ClassNickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com1tag:blogger.com,1999:blog-2827440252127411773.post-30327173531414644142010-11-18T23:30:00.002+02:002011-07-09T01:10:00.375+03:00Bit #24 - Displaying Application Module Pool StatisticsYou can display statistics related to your Application Module Pools by calling <b><i>dumpPoolStatistics()</i></b> on a <i>oracle.jbo.common.ampool.ApplicationPool</i> object. You can acquire an <i>ApplicationPool</i> object by calling <b><i>getResourcePool()</i></b> on a <i>oracle.jbo.common.ampool.PoolMgr</i> object and specifying the name of the application module pool name. So, how do you get a <i>PoolMgr </i>object? Just call the static <i><b>PoolMgr.getInstance()</b></i>. Finally, you can get the pool name by calling <b><i>getResourcePoolKeys()</i></b> on the <i>PoolMgr </i>and enumerating the pools managed by the pool manager. Here is an example:<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Example:</span></b><br />
<i><span class="Apple-style-span" style="font-style: normal;"><br />
</span></i><br />
<i> // helper to dump pool statistics to log<br />
private void dumpAMPoolStatistics() {<br />
// get the pool manager<br />
PoolMgr poolMgr = <b>PoolMgr.getInstance()</b>;<br />
// get the pools managed<br />
Enumeration keys = poolMgr.<b>getResourcePoolKeys()</b>;<br />
if (keys != null) {<br />
if (keys.hasMoreElements()) {<br />
// may manage many pools, we will get the name of first one managed<br />
String poolname = (String)keys.nextElement();<br />
System.out.println("AM pool name: " + poolname);<br />
// get the AM pool<br />
ApplicationPool pool =<br />
(ApplicationPool)poolMgr.<b>getResourcePool</b>(poolname);<br />
<br />
// log AM pool diagnostics<br />
PrintWriter out = new PrintWriter(System.out, true);<br />
pool.<b>dumpPoolStatistics</b>(new PrintWriter(out));<br />
out.flush();<br />
}<br />
}<br />
}<br />
</i><br />
<br />
The helper function above, when added to your application module will display - upon calling it, the AM statistics in the log window as it is shown below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/_Lb-bi4pdlv8/TOWZhwL1sbI/AAAAAAAAA1A/Ko9PFPAKOW0/s1600/TIP24.1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="210" src="http://2.bp.blogspot.com/_Lb-bi4pdlv8/TOWZhwL1sbI/AAAAAAAAA1A/Ko9PFPAKOW0/s320/TIP24.1.png" width="320" /></a></div>
<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Context:</span></b><br />
<br />
BC Implementation Class<br />
<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">References:</span></b><br />
<a href="http://blogs.oracle.com/smuenchadf/resource/examples">83. Dump Application Module Pooling Statistics Servlet</a>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com0tag:blogger.com,1999:blog-2827440252127411773.post-86882783126953836892010-09-07T15:20:00.001+03:002010-09-07T15:25:23.356+03:00Bit #23 - Using findAndSetCurrentRowByKey() to set the View Object currencyYou can set the currency on a View Object (VO) by calling its <b><i>findAndSetCurrentRowByKey()</i></b> method. The method accepts two arguments: a <b><i>Key</i></b> object that is used to locate the row in the VO and an integer indicating the range position of row (for VOs configured with <i>Range Paging Access Mode</i>). Below is an example. The example saves the VO currency, queries the VO and finally restores its currency. Click on the references below to get all the details on the example.<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b>Example:</b></span><br />
<i><br />
/**<br />
* Helper to requery the view.<br />
*/<br />
public void requery() {<br />
Row currentRow = getCurrentRow();<br />
Key currentRowKey = currentRow.getKey();<br />
int rangePosOfCurrentRow = getRangeIndexOf(currentRow);<br />
int rangeStartBeforeQuery = getRangeStart();<br />
executeQuery();<br />
setRangeStart(rangeStartBeforeQuery);<br />
<b>findAndSetCurrentRowByKey(currentRowKey,rangePosOfCurrentRow);</b><br />
}<br />
</i><br />
<span class="Apple-style-span" style="font-size: large;"><b>Context</b></span><br />
<br />
View Object Implementation Class<br />
Application Module Implementation Class<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b>References</b></span><br />
<a href="http://radio-weblogs.com/0118231/2004/11/22.html">http://radio-weblogs.com/0118231/2004/11/22.html</a><br />
<p><span class="Apple-style-span" style="font-size: large;"></span><br />
</p>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com2tag:blogger.com,1999:blog-2827440252127411773.post-9877813367520089262010-07-14T21:55:00.000+03:002010-07-14T21:55:47.034+03:00Bit #22 - Using getPostedAttribute() to determine the posted attribute's valueCall <b><i>getPostedAttribute()</i></b> anywhere in your Entity Object implementation class to retrieve the posted value of an Entity attribute. The example below calls <b><i>getPostedAttribute()</i></b> and <b><i>getAttribute()</i></b> to determine the attribute value in the database (posted) and in the Entity cache (not posted yet) respectively. They are called from within an overridden <b><i>doDML()</i></b>. Then based on the result of comparing them, certain business logic decisions can be made. Note that we call <b><i>getPostedAttribute()</i></b> before calling <b><i>super.doDML()</i></b>. This is done because calling <b><i>super.doDML()</i></b> will in effect post the attribute value in the Entity cache to the database, so will not make much sense to compare them afterwards: <u>They will be the same!</u><br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Example:</span></b><br />
<i><br />
// in your Entity Object Implementation class<br />
<br />
@Override<br />
protected void doDML(int operation, TransactionEvent e) {<br />
<br />
final String EMPLOYEE_ID = "EmployeeId";<br />
<br />
// get posted value of EmployeeId attribute<br />
Object postedEmployeeId = <b>getPostedAttribute(this.getAttributeIndexOf(EMPLOYEE_ID))</b>;<br />
<br />
// get value of EmployeeId before re-posting<br />
Object employeeId = this.getAttribute(EMPLOYEE_ID);<br />
<br />
// compare and take some action based on the results of comparison<br />
if (employeeId != null && employeeId.equals(postedEmployeeId)) {<br />
// do something here <br />
}<br />
<br />
// finally re-post by calling super.doDML()<br />
super.doDML(operation, e);<br />
}<br />
</i><br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Context</span></b><br />
<br />
Entity Object Implementation Class<br />
<b></b>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com0tag:blogger.com,1999:blog-2827440252127411773.post-89332838943020913402010-06-26T11:10:00.000+03:002010-06-26T11:10:47.555+03:00Bit #21 - Overriding prepareSession() to do session-specific initializationsYou can override <i><b>prepareSession()</b></i> in your custom Application Module class to do session-specific initializations, such as invoking a stored procedure to initialize the database state for the specific user, store user information, set application-wide configuration parameters based on the user and so on. The framework invokes <b><i>prepareSession()</i></b> when the Application Module is first checked-out from the Application Module pool for a new user session.<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Example:</span></b><br />
<br />
<i> @Override<br />
protected void prepareSession(Session session) {</i><br />
<i><br />
super.prepareSession(session);<br />
<br />
// do session-specific initializations<br />
}<br />
</i><br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Context:</span></b><br />
<br />
Application Module Implementation Class<br />
<br />
<p></p>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com1tag:blogger.com,1999:blog-2827440252127411773.post-69720546695894335782010-06-23T20:40:00.003+03:002010-06-23T20:53:50.037+03:00Bit #20 - Overriding beforeCommit() to execute custom code before commitOverride the Application Module <i><b>beforeCommit()</b></i> method in your custom Application Module implementation class to execute any custom code that depends on data already posted to the database. Such code may include - but not limited to - validations done in the database via a stored procedure for example. The framework calls this method after <b><i>doDML()</i></b> which means that posted data are available but not yet committed.<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Example:</span></b><br />
<br />
<i>// in your Application Module Implementation class<br />
<br />
@Override<br />
public void beforeCommit(TransactionEvent transactionEvent) {<br />
<br />
// call some stored procedure here<br />
<br />
super.beforeCommit(transactionEvent);<br />
}<br />
</i><br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Context:</span></b><br />
<br />
Application Module Implementation Class<br />
<br />
<o:p></o:p>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com0tag:blogger.com,1999:blog-2827440252127411773.post-11098543614323917772010-06-12T11:27:00.003+03:002010-06-23T20:55:11.401+03:00Bit #19 - Downloading a fileUse an <i><b>af:fileDownloadActionListener</b></i> Rich Faces component to download data from the server to a client machine. Add the listener inside the component that will initiate the download, an <i><b>af:commandButton</b></i> for example, and specify the content type and the name of the file. Also specify a method in a backing bean that will be called to perform the download. In the backing bean method get the formated data to be saved from the model and use the supplied <i>OutputStream</i> to write the data.<br />
<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Example:</span></b><br />
<br />
<i><u>In .jsf page:</u><br />
<br />
<af:commandbutton id="buttonid" " text="Download" ...<br />
<<b>af:filedownloadactionlistener</b> contenttype="application/octet-stream"<br />
method="#{backingBean.doDownload}" filename="defaultFilename.txt"/> <br />
</af:commandButton><br />
<br />
</i><br />
<div><i><u>In backing bean:</u><br />
<br />
public void doDownload(FacesContext facesContext, OutputStream outputStream) {<br />
// write the neccessary code to get the download data from the Model<br />
String data = getDownloadData();<br />
<br />
// save to the output stream<br />
try {<br />
OutputStreamWriter writer = new OutputStreamWriter(outputStream,"UTF-8");<br />
<span class="Apple-style-span" style="font-style: normal;"><i>writer</i></span>.write(data);<br />
<span class="Apple-style-span" style="font-style: normal;"><i>writer</i></span>.close();<br />
outputStream.close();<br />
} catch (IOException e) {<br />
// handle I/O exceptions<br />
}<br />
}<br />
<br />
</i><br />
<b><span class="Apple-style-span" style="font-size: large;">Context:</span></b><br />
<br />
JSF Page<br />
Backing Bean</div><br />
<o:p></o:p>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com3tag:blogger.com,1999:blog-2827440252127411773.post-39028310650051141092010-05-15T22:30:00.003+03:002010-06-23T20:49:00.003+03:00Bit #18 - Dynamically changing the View Object's query WHERE clauseYou can dynamically change the <i>View Object's (VO)</i> query <i>WHERE</i> clause by overriding the <i><b>buildWhereClause()</b></i> <i>VO </i>method. When doing so, ensure that you call the base class' <i><b>buildWhereClause()</b></i> first, to let the framework do its processing before making your own changes. The <i><b>StringBuffer </b></i>parameter that is passed to the method is the complete query SQL statement. Do your changes directly onto it. When done, make sure that you return appropriately a true/false boolean to indicate whether a <i>WHERE </i>clause was appended to the query or not. Here is an example.<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Example:</span></b><br />
<i><span class="Apple-style-span" style="font-style: normal;"><br />
</span></i><br />
<i> @Override<br />
protected boolean <b>buildWhereClause</b>(StringBuffer sqlBuffer, int noBindVars) {<br />
<br />
// call ViewObjectImpl's buildWhereClause() to allow the framework to do its processing<br />
boolean hasWhereClause = super.<b>buildWhereClause</b>(sqlBuffer, noBindVars);<br />
<br />
if (hasWhereClause) { // framework added a WHERE clause<br />
// modify the WHERE clause as needed<br />
}<br />
else { // framework did not add a WHERE clause, so we need to add it ourselves<br />
// add a WHERE clause here<br />
hasWhereClause = true; // ensure that is set to notify the framework<br />
}<br />
<br />
return hasWhereClause; // return true/false to indicate whether a WHERE clause was added<br />
}<br />
</i><br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Context:</span></b><br />
<br />
View Object Implementation<br />
<br />
<o:p></o:p>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com3tag:blogger.com,1999:blog-2827440252127411773.post-48159435605427633262010-05-10T21:19:00.001+03:002010-05-10T21:19:57.089+03:00Bit #17 - Using the securityContext bean in a JSF pageTo acess the user's authentication information from within a JSF page, use the <i><b>securityContext</b></i> bean and any of its available methods. For instance, using <i>Expression Language (EL)</i>, the following will return true/false indicating whether the user is authenticated or not: <i><b>#{securityContext.authenticated}</b></i>. Similarly, to determine whether the user has been assigned a specific role, use the following <i>EL</i> snippet <i><b>#{securityContext.userInRole['SomeRole']}</b></i>. It will return true if the user has been assigned the specific role.<br />
<br />
<br />
<b><span style="font-size: large;">Example:</span></b><br />
<br />
<i> // in the context of a JSF page<br />
<br />
<af:commandLink id="login_logout" action = "#{securityContext.authenticated ? 'logout' : 'login'}" text="#{securityContext.authenticated ? 'Logout' : 'Login'}/><br />
<br />
<af:commandToolbarButton id="delete" actionListener="#{backingBean.delete}" disabled="#{securityContext.userInRole['CanDelete']==false}" text="Delete"/></i><br />
<br />
<br />
<b><span style="font-size: large;">Context:</span></b><br />
<br />
JSF Page<br />
<p></p>Nickhttp://www.blogger.com/profile/06649943531692175880noreply@blogger.com0