Thursday, December 30, 2010

Hiding a view criteria Item from af:query

Define a Binding for the af:query and in its setter method write this code

Where TopicVO1Iterator is the ViewObject,findByTitleCriteria is the VC and ABSTRACT_SUMMARY is the ColumnName attr for the VC.

    public void setRichQuery(RichQuery richQuery) {
this.richQuery = richQuery;
DCIteratorBinding iter = ADFUtil.getDCIteratorBinding("TopicVO1Iterator");
ViewObjectImpl voimpl = (ViewObjectImpl)iter.getViewObject();
ViewCriteria vc = voimpl.getViewCriteriaManager().getViewCriteria("findByTitleCriteria");
while(vc.hasNext()){
ViewCriteriaRow vcr = (ViewCriteriaRow)vc.next();
if (vcr != null) {
ViewCriteriaItem[] vcis = vcr.getCriteriaItemArray();
for (ViewCriteriaItem vci : vcis) {
if(vci != null && "ABSTRACT_SUMMARY".equals(vci.getColumnName()))
vci.setProperty(ViewCriteriaItemHints.CRITERIA_RENDERED_MODE,
ViewCriteriaItemHints.CRITERIA_RENDERED_MODE_NEVER);
}
}
}
}

Friday, July 23, 2010

ADFbc:sharedAM usage standards

Following are the Standards for SharedAM usage.

* Make sure, no duplicate definitions of the SharedAM configurations entries with different scope usages from multiple projects's .jpx files.
* Make sure, there shouldnt be any references to DataControl usage for SharedAM from the projects
* SharedAM usage name should be unique across all projects in an J2EE Application.i.e in ViewAccessors from a Shared AM VO.
* SharedAM shouldn't used for transactional purpose

Wednesday, July 07, 2010

ADF Serialization of Objects testing from JDev.

Add the following to weblogic.xml:

<session-descriptor>
<cache-size>0</cache-size>
<persistent-store-type>FILE</persistent-store-type>
</session-descriptor>

Add the following to the Run/Debug java options:

-Dorg.apache.myfaces.trinidad.CHECK_STATE_SERIALIZATION=session,tree

Add this to the adf-config.xml:

<adf-controller-config xmlns="http://xmlns.oracle.com/adf/controller/config">
<adf-scope-ha-support>true</adf-scope-ha-support>
</adf-controller-config>

Wednesday, June 02, 2010

Catch the error raised by your bounded Taskflow

We have scenarios where we consume other third party bounded taskflows.It depends, how well a developer has designed the bounded taskflow.If he has not included an Exception Handler activity in his bounded Taskflow, then for any unhandled exception, the consumer ADF/JSF page blows off.

Best practice is to include an Exception Handler activity in the Bounded taskflow.

Here is a piece of code that can be used to show the errors raised by the Taskflow.This should be kept in your Exception activity's view jsff.

  <af:message id="m1"
message="Error is--->#{controllerContext.currentViewPort.exceptionData.message}" messageType="error"
rendered="#{controllerContext.currentViewPort.exceptionPresent}"/>

Monday, May 31, 2010

ADF:Sorting a Programmatic/Transient ViewObject

Often we use Transient ViewObject to store In-Memory data to represent in UI or manipulate business logic.
We may need to sort these Transient ViewObjects based on certain attribute.

MyTransVO.setSortBy("AttributeName");
MyTransVO.setQueryMode(ViewObject.QUERY_MODE_SCAN_VIEW_ROWS);
MyTransVO.executeQuery();

Monday, May 24, 2010

ViewCriteria in Shared AM-Reuse BindVariable and QueryCollection from Cache

A VO on a sharedAM caches multiple rowsets by the bind variables. So if you query a VO 5 times with 5 different bind variables, it does cache 5 rowsets. And if you go back and requery by those same bind variables you dont not see any database I/O

Here is a sample code

    public void applyVC() {
EmpVOImpl vo = this.getEmpVO1();

ViewCriteria vc = vo.getViewCriteria("findByEmpId");
vo.setNamedWhereClauseParam("pEmpId", "931");
vo.applyViewCriteria(vc);
vo.refreshCollection(null, true, true);
vo.reset();

int rowcount = 0;
while (vo.hasNext()) {
Row row = vo.next();
rowcount++;
}
System.out.println("Total # of rows = " + rowcount);

}


Execute this multiple times from AM tester or from ADF UI and you will see the difference.

Important note is,instead of executeQuery() you should use refreshFromCollection() so that the Rowset is resued from QueryCollection cache.

Technical Analysis
For SharedAM,Once the RowSet is closed, the QueryCollection will be released to the QueryCollection cache and potentially reused upon the next request.

ADFbc:Common Util class for testing CRUD operation of an EO based VO

A simple common util class that your Junit class can extend for verifying standard CRUD operation for a a single EO based VO.

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import oracle.jbo.Key;
import oracle.jbo.Row;
import oracle.jbo.server.AttributeListImpl;
import oracle.jbo.server.ViewObjectImpl;


public class AtkCommonVOActionsTest {
public AtkCommonVOActionsTest() {
super();
}

public Row testCreateRow(ViewObjectImpl viewObject, Map<String,Object> attributeList){
AttributeListImpl initVals = createAttributeList(attributeList);
Row row = viewObject.createAndInitRow(initVals);
return row;
}

public Row testUpdateRow(ViewObjectImpl viewObject, Map<String,Object> attributeList, Key pkObject){
if(pkObject != null){
Row[] rows = viewObject.findByKey(pkObject, 1);
if(rows != null && rows.length > 0){
Row row = rows[0];
List<String> keyList = getKeyList(attributeList);
List<Object> valueList = getValueList(attributeList);
row.setAttributeValues(keyList, valueList);
return row;
}

}
return null;
}


public Row testDeleteRow(ViewObjectImpl viewObject, Key pkObject){
if(pkObject != null){
Row[] rows = viewObject.findByKey(pkObject, 1);
if(rows != null && rows.length > 0){
Row row = rows[0];
row.remove();
return row;
}
}
return null;
}



private AttributeListImpl createAttributeList(Map<String,Object> attributeList){
AttributeListImpl attrList = new AttributeListImpl();
Iterator<String> keys = attributeList.keySet().iterator();
while(keys.hasNext()){
String key = keys.next();
Object value = attributeList.get(key);
attrList.setAttribute(key, value);
}
return attrList;
}

private List<String> getKeyList(Map<String,Object> attributeList){
List<String> keyList = new ArrayList<String>();
Iterator<String> keys = attributeList.keySet().iterator();
while(keys.hasNext()){
String key = keys.next();
keyList.add(key);
}
return keyList;
}

private List getValueList(Map<String,Object> attributeList){
List valueList = new ArrayList();
Iterator<String> keys = attributeList.keySet().iterator();
while(keys.hasNext()){
String key = keys.next();
Object value = attributeList.get(key);
valueList.add(value);
}
return valueList;
}



}

Monday, May 17, 2010

ADF input forms generator (from XSD to a web page)

Requirement
There is one XSD file which has is "Define Conuntry application input data definition".
So it defines all the data you have to fill in to create a Country info. XSD defines which fileds are mandatory and which are optional.
We would like to create an internet service to allow creating/displaying a Country.

Example
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.oracle.com/pcbpel/CountryInfo"
elementFormDefault="qualified">
<element name="CountryInfo">
<complexType>
<sequence>
<element name="Country" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="Name" type="string"/>
<element name="Capital" type="string"/>
<element name="Area" type="decimal"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>


Solution
1)-In JDev, Select the XSD in the Applications Navigator.
2)- Right Click the xsd file and select "Generate JAXB2.0 contet Model".
3)-It generates the required java files.
4)-Right click the relevant Java file(e.g in this case , CountryInfo.java)
5)-Select "Create Data Control" and generate the .dcx file.

Now you can use this Data Control to drag and drop to build any ADF component such as a Form Layout or a Table etc etc.

Bottom Line is somehow you need to create a DataControl out of the XSD file to use that declaratively to build an ADF UI.

Note
You can also generate the Webservice out of these XSD through JAXB and expose that to build UI, either using ADF datacontrol or any standard J2EE solution.

Saturday, May 15, 2010

ADF:Bring a specific row in a VO to the top slot

Requirement
You have a view object populated with some rows.You want to put a specific row(identified by a PK attribute) at the top of the VO query collection.

Example
if(pEmpno != null){
Row foundEmpRow = empVO.getRow(new Key(new Object[]{pEmpno}));
if(foundEmpRow != null){
ViewObjectImpl empVOImpl = (ViewObjectImpl)empVO;
empVOImpl.getQueryCollection().remove(foundEmpRow);
empVOImpl.getQueryCollection().add(0, foundEmpRow);
}
}

Tuesday, May 11, 2010

EntityObject:Creating your own History Attributes

ADF Entity Objects allows a functionality to define History Attributes for the Entity Objects.Such as "CreatedOn","ModfiedOn","CreatedBy","ModifiedBy" etc etc.

For your application, if you want you can introduce/extend these History Attributes from the JDev preference.

Steps To create a custom history type:

From the Tools menu, choose Preferences.
In the Preferences dialog, expand Business Components, and click History Types.
On the History Types page, click New.
In the Create History Type dialog, enter a string value for the name (spaces are allowed) and a numerical Id.
Open the EntityImpl.java file and add a definition for the numerical id such as
private static final byte MYCUSTOM_HISTORY_TYPE = 20;

Override the getHistoryContextForAttribute(AttributeDefImpl attr) method in the EntityImpl base class

@Override
protected Object getHistoryContextForAttribute(AttributeDefImpl attr) {
if (attr.getHistoryKind() == MYCUSTOM_HISTORY_TYPE) {
// Custom History type logic goes here
}
else {
return super.getHistoryContextForAttribute(attr);
}
}

Monday, May 03, 2010

Mapping ADF(Faces + ADFbc) to J2EE MVC

An interesting mail I found today.Simple and explanatory.

How to map the ADF application projects to J2EE MVC Architecture.

To be simple..
MODEL (M in MVC):
what ever you see in Model.jpr(which contains ADF BC componenets like EO,VO,AM ) . Interestingly they call this as Business Services in ADF and call "Data Bindings" and "Data Controls" as ADF Model. Data Controls(Application Modules) will be part of your Model.jpr and Data Bindings will be part of your UI.jpr.
So, Simply MODEL means combination of Data Bindings and Data Controls in ADF
It can be ADFbc,TopLink,EJB, even POJOs.

View (V in MVC):
View is simply what ever user see and interact with application. So, what ever u see under UI.Jpr like .jsff, .jspx, Flow.xml etc.. all these comes under View Componenets. You can see lot many XML files under UI.jpr, like PageDef.xml(this is where you will have your page level Data Bindings) and other configuration files(like web.xml, adfc-config.xml etc..)

Controller (C in MVC):
Unfortunately you can't map declaratively as we do for M and V. But, in ADF controller is "FacesServlet" which is the first controller java servlet which will listen to user request and initiate the faces life cycle process. In most of the Web frameworks(like , Struts, JSF) a servlet acts as a controller. So, here in ADF it is "FacesServlet"(you can search for this entry in web.xml). "FacesServlet" job is to listen to user request and decide which View to be shown to the user by interacting with which Model Components.
(Note: In Jdev, Controller basically resides in UI project itself, thats why they name UI project as ViewControler (where as Model project name is Model))

ADF:Check if there are pending changes in UI

Situations arise when we may need to check if there is any pending transactions in the ADF UI.
You can do it easily from ADFbc.

Use DBTransactionImpl.isDirty()

Or From ADF Faces side

BindingContext bctx = oracle.adf.controller.binding.BindingUtils.getBindingContext();
bctx.findDataControlFrame(bctx.getCurrentDataControlFrame()).isTransactionDirty();

Wednesday, April 28, 2010

ADF:usage of RowQualifier

A useful note , for those who are not aware of this cool feature of ADFbc..
Like we apply ViewCriteria on the ViewObject, we can apply similar SQL structured WHERE clause predicate on the ViewObject ResultCache in middle tier..(not in the DB)...using RowQualifier(oracle.job.server.RowQualifier)

            //Create a new RowQualifier object with the filtering condition.
RowQualifier qualf = new RowQualifier("ApplicationId = "+applicationId+" AND ContextName ='"+contextName+"'");

//Filtered the rowset based on Attribute applicationId and the value user passes.
Row[] rows = getContextVO().getFilteredRows(qualf);


The above Rowqualifier constructs a middle tier WHERE clause predicate and apply on the ViewObject resultset.

The major advantage of RowQualifier on VC is, like VC we dont need a design time artifact on VO, nor do we need to write complicated code for programmatic implementation..This is quick and instantaneous..

ADF:getBindingContainer in JDev 11g

No need of evaluating :#{bindings} EL expression..
Simply use the direct API call

  /* Get the current binding container */
BindingContainer bc = BindingContext.getCurrent().getCurrentBindingsEntry();
/* Lookup and invoke the action binding named "yourMethodName" */
Object retVal = bc.getOperationBinding("yourMethodName").execute();

PLSQL:handy script to truncate tables of your choice

declare
cursor cur_tables IS
select table_name from user_tables where table_name like 'EMP%';
begin
for c_rec in cur_tables LOOP
execute immediate 'truncate table '||c_rec.table_name;
end loop;
end;

Me and Mama

ADF af:carousel implementation

af:carousel implementation is really easy.Dont get afraid.

You have a ViewObject say DepartmnentsVO exposed in a DataControl(i.e AM).
From DataControl pallete, drag and drop the VO as af:carousel onto your page.
It creates a Tree binding in the pagedef automnatically and an af:carousel UI component.
Interesting thing in the Jspx/Jsff page for af:carousel is the var property usage.
See the sample code below.

Jspx code

              <af:carousel currentItemKey="#{bindings.DepartmentsView1.treeModel.rootCurrencyRowKey}"
value="#{bindings.DepartmentsView1.treeModel}"
var="item" id="c1"
carouselSpinListener="#{SpinHelper.onSpin}">
<f:facet name="nodeStamp">
<af:carouselItem id="ci1">
<af:panelFormLayout id="pfl1">
<f:facet name="footer"/>
<af:panelLabelAndMessage label="#{item.bindings.DepartmentId.hints.label}" id="plam1">
<af:outputText value="#{item.bindings.DepartmentId.inputValue}" id="ot1"/>
</af:panelLabelAndMessage>
<af:panelLabelAndMessage label="#{item.bindings.DepartmentId.hints.label}"
id="panelLabelAndMessage1">
<af:outputText value="#{item.bindings.DepartmentName.inputValue}"
id="outputText1"/>
</af:panelLabelAndMessage>
<af:panelLabelAndMessage label="#{item.bindings.ManagerId.hints.label}"
id="panelLabelAndMessage3">
<af:outputText value="#{item.bindings.ManagerId.inputValue}"
id="outputText3"/>
</af:panelLabelAndMessage>
<af:panelLabelAndMessage label="#{item.bindings.LocationId.hints.label}"
id="panelLabelAndMessage2">
<af:outputText value="#{item.bindings.LocationId.inputValue}"
id="outputText2"/>
</af:panelLabelAndMessage>
</af:panelFormLayout>
</af:carouselItem>
</f:facet>
</af:carousel>


PageDef code
    <tree IterBinding="DepartmentsView1Iterator" id="DepartmentsView1">
<nodeDefinition DefName="adf.sample.model.DepartmentsView"
Name="DepartmentsView10">
<AttrNames>
<Item Value="DepartmentId"/>
<Item Value="DepartmentName"/>
<Item Value="ManagerId"/>
<Item Value="LocationId"/>
</AttrNames>
</nodeDefinition>
</tree>

ADF security-programming artifacts

All should be self explanatory.

#{securityContext.authenticated}
#{securityContext.userName}
#{securityContext.taskflowViewable['/WEB-INF/TaskFlowColor.xml#TaskFlowColor']}
#{securityContext.regionViewable['mypackage.page1']}
#{securityContext.userInRole['role1,role2,roleN']}
#{securityContext.userInAllRoles['role1,role2,roleN']}

Adding templates to your DefaultDomain JDev Integrated WLS Server

shutdown integrated WLS from JDev.
Close Jdev
run $mw_home/jdeveloper/oracle_common/common/bin/wlst.sh

Then execute the following codes in the wlst>

readDomain('....full path to jdev default domain...')
addTemplate('$MW_HOME/jdeveloper/common/templates/applications/TheTemplateYouWant.jar')
updateDomain()
exit()

* Start JDev.
* Start JDev integarted Default server.
* Go to localhost:7101/console
* Deployments

SortCriteria in pageDef iterators-Override ViewObject OrderBy

We have Order By clause for ADFbc view object so that the Data renders in specific order.
Likewise, we can override the default ViewObject OrderBy in PageDef iterator using sortCriteria to render a different orders set of data in the Jspx/Jsff page.

<iterator Binds="Emp" DataControl=MyAMDataControl"
id="EmpVOIter" RangeSize="25">
<sortCriteria>
<sort attribute="Ename" ascending="true"/>
</sortCriteria>
</iterator>


Caution
It tries to sort the iterator every time it executes.Hence a little bit additional work.

ADF/JSF way of finding all UIComponents in a DOM Recusrively

CAUTION:This is expensive and must be done only when the UIComponents are static, i.e rendered property is not EL expressed.

public static HashMap<String, UIComponent> viewCompMap =  new HashMap<String, UIComponent>();


public static HashMap<String, UIComponent> populateViewComponentsMap(HashMap<String, UIComponent> compMap) {
FacesContext fc = FacesContext.getCurrentInstance();
//Gets the ui view root component.
UIComponent uiComp = (UIComponent)fc.getViewRoot();
//Puts the ui view root component into static map.
compMap.put(uiComp.getId(), uiComp);
//Calls the recursive method which walks down the view tree and populates them in the static map.
populateChildrenInMap(uiComp, compMap);
return compMap;
}

public static void populateChildrenInMap(UIComponent uiComp,
HashMap<String, UIComponent> compMap) {
//Checks if the compMap is not null.
if (uiComp != null) {
//Gets all the children of the ui component as an iterator.
Iterator<UIComponent> uiCompChildren =
uiComp.getFacetsAndChildren();
if (uiCompChildren != null) {
//Iterates through the children.
while (uiCompChildren.hasNext()) {
UIComponent child = uiCompChildren.next();
if (child != null) {
//puts the child component in the map.
compMap.put(child.getId(), child);
}
//Calls the recursive method for each of the child component.
populateChildrenInMap(child, compMap);

}
}

}
}

ADFway of rendering a BLOB from a Servlet

Say, you have a BLOB in one of your DB table column.
You want to stream the BLOB onto your ADF page.How to do it?

The ViewOBject contains 4 columns.
PrimaryKey,FileName,MimeType and Blob

Here is the servlet code involving ADFbc.

public ApplicationModule getHPApplicationModuleFromPool(){
try{
//Get the ApplicationModule Client Interface and get the MyVO
String amDef = "mypackage.applicationModule.MyAM";
String amConfig = "MyAMLocal";
ApplicationModule am =
Configuration.createRootApplicationModule(amDef, amConfig);

return am;

}catch(Exception e){
e.printStackTrace();
}

return null;

}


public void blobProcessing(String primaryKey) {
ApplicationModule am = null;
try{
{
//Get the Row for the Passed TopicId
Key key = new Key(new Object[]{primaryKey});
am = getHPApplicationModuleFromPool();
ViewObject vo = am.findViewObject("MyVo");

Row row = vo.getRow(key);
if(topicRow != null){
String fileName = (String)row.getAttribute("FileName");
mimeType = (String)row.getAttribute("MimeType");
//Sets the MimeType
response.setContentType(mimeType != null ? mimeType : "application/octet-stream");
//Sets the content disposition style
response.addHeader("Content-Disposition", "inline; filename="+ fileName);
//Read the row.getBlob() and redirect to an outPutStream
BlobDomain blobContent = (BlobDomain)row.getAttribute("Blob");
//gets the ByteArray from BlobDomain
byte[] bytearray = topicContent.toByteArray();
//gets the Binary InputStream from BlobDomain
InputStream reader = blobContent.getBinaryStream();;
int size = 0;
//Read the InputStream and write to Servlet's output Stream.
while ((size = reader.read(bytearray)) != -1)
response.getOutputStream().write(bytearray,0,size);
//Close the reader stream
reader.close();
}
Configuration.releaseRootApplicationModule(am, false);
}//End Blob processing

}catch(Exception e){
try{
if(am != null)
Configuration.releaseRootApplicationModule(am, false);
e.printStackTrace();
}catch(Exception e1){
e1.printStackTrace();
}
}
}


JSF/ADF way of getting Browser Name and Version

Here is how you can identify the browser version and Name in your JSF or ADF application.

#{requestContext.agent.agentName}
#{adfFacesContext.agent.agentVersion}

Common Utility Methods for ADF Faces

There are common utility and very frequently used Helper methods to work with ADFm.

ADFUtil.java

import java.util.HashMap;
import java.util.Locale;

import java.util.Map;

import java.util.ResourceBundle;

import javax.el.ELContext;

import javax.el.ExpressionFactory;

import javax.el.MethodExpression;
import javax.el.ValueExpression;

import javax.faces.context.FacesContext;

import oracle.adf.model.BindingContext;
import oracle.adf.model.DataControlFrame;
import oracle.adf.model.binding.DCBindingContainer;
import oracle.adf.model.binding.DCIteratorBinding;

import oracle.javatools.resourcebundle.BundleFactory;
import oracle.javatools.resourcebundle.NamedMessageFormat;


/**
* Provides various utility methods that are handy to
* have around when working with ADF.
*/
public class ADFUtil {

/**
* When a bounded task flow manages a transaction (marked as requires-transaction,.
* requires-new-transaction, or requires-existing-transaction), then the
* task flow must issue any commits or rollbacks that are needed. This is
* essentially to keep the state of the transaction that the task flow understands
* in synch with the state of the transaction in the ADFbc layer.
*
* Use this method to issue a commit in the middle of a task flow while staying
* in the task flow.
*/
public static void saveAndContinue() {
Map sessionMap =
FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
BindingContext context =
(BindingContext)sessionMap.get(BindingContext.CONTEXT_ID);
String currentFrameName = context.getCurrentDataControlFrame();
DataControlFrame dcFrame =
context.findDataControlFrame(currentFrameName);

dcFrame.commit();
dcFrame.beginTransaction(null);
}

/**
* Programmatic evaluation of EL.
*
* @param el EL to evaluate
* @return Result of the evaluation
*/
public static Object evaluateEL(String el) {

FacesContext facesContext = FacesContext.getCurrentInstance();
ELContext elContext = facesContext.getELContext();
ExpressionFactory expressionFactory =
facesContext.getApplication().getExpressionFactory();
ValueExpression exp =
expressionFactory.createValueExpression(elContext, el,
Object.class);

return exp.getValue(elContext);
}

/**
* Programmatic invocation of a method that an EL evaluates to.
* The method must not take any parameters.
*
* @param el EL of the method to invoke
* @return Object that the method returns
*/
public static Object invokeEL(String el) {

return invokeEL(el, new Class[0], new Object[0]);
}

/**
* Programmatic invocation of a method that an EL evaluates to.
*
* @param el EL of the method to invoke
* @param paramTypes Array of Class defining the types of the parameters
* @param params Array of Object defining the values of the parametrs
* @return Object that the method returns
*/
public static Object invokeEL(String el, Class[] paramTypes,
Object[] params) {

FacesContext facesContext = FacesContext.getCurrentInstance();
ELContext elContext = facesContext.getELContext();
ExpressionFactory expressionFactory =
facesContext.getApplication().getExpressionFactory();
MethodExpression exp =
expressionFactory.createMethodExpression(elContext, el,
Object.class, paramTypes);

return exp.invoke(elContext, params);
}

/**
* Sets a value into an EL object. Provides similar functionality to
* the &lt;af:setActionListener&gt; tag, except the <code>from</code> is
* not an EL. You can get similar behavior by using the following...<br>
* <code>setEL(<b>to</b>, evaluateEL(<b>from</b>))</code>
*
* @param el EL object to assign a value
* @param val Value to assign
*/
public static void setEL(String el, Object val) {

FacesContext facesContext = FacesContext.getCurrentInstance();
ELContext elContext = facesContext.getELContext();
ExpressionFactory expressionFactory =
facesContext.getApplication().getExpressionFactory();
ValueExpression exp =
expressionFactory.createValueExpression(elContext, el,
Object.class);

exp.setValue(elContext, val);
}

/**
* Get the BindingCOntainer reference.
* Then based on the IteratorName, return the DCIteratorBinding.
*
* @param String iteratorName
* @return DCIteratorBinding
*/
public static DCIteratorBinding getDCIteratorBinding(String iteratorName) {

FacesContext fctx = FacesContext.getCurrentInstance();
ExpressionFactory exp = fctx.getApplication().getExpressionFactory();

DCBindingContainer bc;
bc =
(DCBindingContainer)exp.createValueExpression(fctx.getELContext(), "#{bindings}",
DCBindingContainer.class).getValue(fctx.getELContext());

DCIteratorBinding iter = bc.findIteratorBinding(iteratorName);
return iter;
}


}

Debgging Javascript issues in ADF app

To help make debugging easier add the below context params to your ADF web application's web.xml

<context-param>
<param-name>org.apache.myfaces.trinidad.DISABLE_CONTENT_COMPRESSION</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.trinidad.DEBUG_JAVASCRIPT</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>oracle.adf.view.rich.LOGGER_LEVEL</param-name>
<param-value>WARNING</param-value>
</context-param>


Then restart the server.

ADF:Programatically adding Bookmark in FF3

FireFox has a limitation of creating Bookmarks using Javascript.Till FF2.X version, it used to open in Browser Side Bar.

Here is a piece of code in ADF you can use.

JSFF/JSPX code
<af:commandbutton text="BookMark Me" id="cb1" actionlistener="#{DemoBean.invokeBookMark}" partialsubmit="true">
</af:commandbutton>


Managed Bean code
 private String FIREFOX_BOOKMARK_SCRIPT = " alert('in FF');     netscape.security.PrivilegeManager.enablePrivilege(\"UniversalXPConnect\"); \n" +
" var bmsvc = Components.classes[\"@mozilla.org/browser/nav-bookmarks-service;1\"].getService(Components.interfaces.nsINavBookmarksService); \n" +
" var ios = Components.classes[\"@mozilla.org/network/io-service;1\"].getService(Components.interfaces.nsIIOService); \n" +
" var uri = ios.newURI(url, null, null); \n" +
" var hpBookMarkId = bmsvc.insertBookmark(bmsvc.bookmarksMenuFolder, uri, bmsvc.DEFAULT_INDEX, title); \n" +
" alert('hpBookMarkId='+hpBookMarkId);";


public void invokeBookMark(ActionEvent actionEvent) {
// Add event code here...

String title = "XXXX";
String url = "http://127.0.0.1:7104/contextRoot/faces/MyPage";
String script = "var title='" + title + "'; " + "var url='" + url + "'; " + BOOKMARK_JAVASCRIPT;

ExtendedRenderKitService service =
Service.getRenderKitService(FacesContext.getCurrentInstance(),
ExtendedRenderKitService.class);

service.addScript(FacesContext.getCurrentInstance(), script);

}



Note:

However, for browser scripting security in FF 3,0, user have to do the following.I have updated the same in the bug.
This is a normal web world practice, nothing specific to JSF or ADF.

1)-In Firefox browser,in address location type "about:config" and reload the tab.
2)-It will prompt for a message.Say Yes.
3)-Out of the list of properties, search for "signed.applets.codebase_principal_support".
4)-Double click on the value "false" and it becomes true.

Close the browser and try clicking Bookmark Icon for the HelpPortal Topic.
Make sure you check the checkbox "Remember this decision", when FireFox will display this message.

Thursday, April 22, 2010

Java:Wrap a HTML word with some HTML tags

Input : A Given HTML String
Output : A formatted HTML string with a word wrapped up with some HTML tags.

String startTag = "";
String endTag = "
";
String title = "Hi My Name is AMulya Mishra";
String keyWord = "AMulya";

title = title.replaceAll("(?i)\\b\\p{Alpha}*" + keyWord + "\\p{Alpha}*\\b",startTag + "$0" + endTag);


output = "Hi My Name is AMulya Mishra"

Refreshing SharedAM viewobjects periodically

SharedAM viewobjects get instantiated once per JVM life cycle.In the mean time , if we have a requirement to have the ViewObjects of the SharedAM reflect the latest changes of Data from underlying Database Tables, we have a programmatic way to do so.

public long lastRefreshedTime;

private void setLastRefreshedTime(long lastRefreshedTime) {
this.lastRefreshedTime = lastRefreshedTime;
}

private long getLastRefreshedTime() {
return lastRefreshedTime;
}


private void refreshSharedAMVOs() {
String[] voNames = this.getViewObjectNames();
for (String voName : voNames) {
ViewObjectImpl vo = (ViewObjectImpl)this.findViewObject(voName);
processDatabaseChangeNotification(vo);
}
}


public void refreshSharedAM() {

long currentTime = System.currentTimeMillis();
long lastRefreshedTime = getLastRefreshedTime();

//hardcoded to 1 day
if ((currentTime - lastRefreshedTime) > 12 * 60 * 60 * 1000) {
synchronized (this) {
refreshSharedAMVOs();
}
setLastRefreshedTime(currentTime);
}
}

private void processDatabaseChangeNotification(ViewObjectImpl vo) {
try {
Row currentRow = vo.getCurrentRow();

if (currentRow == null) {
int rangeStartBeforeQuery = vo.getRangeStart();
vo.executeQuery();
vo.setRangeStart(rangeStartBeforeQuery);
} else {
Key currentRowKey = currentRow.getKey();
int rangePosOfCurrentRow = vo.getRangeIndexOf(currentRow);
int rangeStartBeforeQuery = vo.getRangeStart();
vo.executeQuery();
vo.setRangeStart(rangeStartBeforeQuery);
vo.findAndSetCurrentRowByKey(currentRowKey,
rangePosOfCurrentRow);
}

} catch (Exception e) {
e.printStackTrace();
}
}


ADF 11g JavaScript Doc

ADF exposes a whole lot of JavaScript APIs.
http://download.oracle.com/docs/cd/E12839_01/apirefs.1111/e12046/overview-summary.html

Back to Blogging

After quite sometime(May be after 2 years) , am back to my blogging.