Sunday, December 9, 2012

Active Data Service With Active Image andActive Output text

Hi

In my last post i have explained about active data with bar graph component that was little bit tricky but for implementing active data service with active image and  active output text are easy to implements.

Implementation of Active Data Service with Active Image :

Step 1:Extends BaseActiveDataModel class and override method.Code is following

package com.blog.example.image.model;

import java.util.ArrayList;
import java.util.Collection;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import java.util.concurrent.atomic.AtomicInteger;

import oracle.adf.view.rich.activedata.ActiveModelContext;
import oracle.adf.view.rich.activedata.BaseActiveDataModel;
import oracle.adf.view.rich.event.ActiveDataEntry;
import oracle.adf.view.rich.event.ActiveDataUpdateEvent;

import oracle.adfinternal.view.faces.activedata.ActiveDataEventUtil;

public class ImageActiveModelClass extends BaseActiveDataModel
{
    private final AtomicInteger changeCounter = new AtomicInteger();
    private static final Timer timer = new Timer();
    private final AtomicInteger counter = new AtomicInteger(0);
    List<String> list = new ArrayList<String>();
    private String image = "/image/graphPage.png";
    static int j = 0;

    public ImageActiveModelClass() {
        super();
        list.add("/image/inde1x.jpg");
        list.add("/image/index.jpg");
        list.add("/image/index2.jpg");
        list.add("/image/index3.jpg");
        list.add("/image/index4.jpg");
        list.add("/image/index7.jpg");
        list.add("/image/index8.jpg");
        list.add("/image/index9.jpg");
        list.add("/image/index10.jpg");
        list.add("/image/index11.jpg");
        ActiveModelContext context =
            ActiveModelContext.getActiveModelContext();
        Object[] keyPath = new String[0];
        context.addActiveModelInfo(this, keyPath, "image");
        timer.schedule(new UpdateTask(), 2000, 2000);
    }

    protected void startActiveData(Collection<Object> collection, int i) {
    }

    protected void stopActiveData(Collection<Object> collection) {
    }

    @Override
    public int getCurrentChangeCount() {
        return changeCounter.get();
    }


    public void setImage(String image) {
        this.image = image;
    }

    public String getImage() {
        return image;
    }

    protected class UpdateTask extends TimerTask {
        public void run() {
            counter.incrementAndGet();
            ActiveDataUpdateEvent event =
                ActiveDataEventUtil.buildActiveDataUpdateEvent(ActiveDataEntry.ChangeType.UPDATE,
                                                               counter.get(),
                                                               new String[0],
                                                               null,
                                                               new String[] { "image" },
                                                               new Object[] { list.get(j) });
            fireActiveDataUpdate(event);
            j = j + 1;
            if (j == 10) {
                j = 0;
            }
        }
    }

}

Step2: For register active image with ads i have written following code

        ActiveModelContext context =
            ActiveModelContext.getActiveModelContext();
        Object[] keyPath = new String[0];
        context.addActiveModelInfo(this, keyPath, "image");

Step3:Register ImageActiveModelClass class in adfc-config.xml with session scope

<?xml version="1.0" encoding="windows-1252" ?>
<adfc-config xmlns="http://xmlns.oracle.com/adf/controller" version="1.2">
  <managed-bean id="__2">
    <managed-bean-name id="__4">imageActive</managed-bean-name>
    <managed-bean-class id="__3">com.blog.example.image.model.ImageActiveModelClass</managed-bean-class>
    <managed-bean-scope id="__1">session</managed-bean-scope>
  </managed-bean>
  <managed-bean id="__6">
    <managed-bean-name id="__8">outPutActive</managed-bean-name>
    <managed-bean-class id="__5">com.blog.example.output.model.OutPutActiveDataModel</managed-bean-class>
    <managed-bean-scope id="__7">session</managed-bean-scope>
  </managed-bean>
</adfc-config>

Step 4:jspx code is following

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
  <jsp:directive.page contentType="text/html;charset=UTF-8"/>
  <f:view>
    <af:document id="d1">
      <af:form id="f1">
        <af:activeImage source="#{imageActive.image}" id="ai1"/>
        <af:activeOutputText id="aot1" value="#{outPutActive.outPut}"/>
      </af:form>
    </af:document>
  </f:view>
</jsp:root>


Same step i have implemented for active out put text also.you can find code at following link.

Link is

https://docs.google.com/open?id=0B8cP4jZuxLlXN2pQYzN6Ql91Vlk


Thank,
Prateek


Saturday, December 8, 2012

Active Data Serivce With Data Visualizations Graph Component (DVT)

Hi ,

In this post i would like to show how dvt component will work with active data service.Since there is no example available on internet therefore might it will very useful for reader.

Use Case: Bar Graph integration with Active Data Service.

The Importance Step for implementing Active Data Service are following.

1-Need to provide configuration for Active Data Service  adf-config.xml
2-Create the Model for Active Data Service.
   In Graph context the model will have following data structure.
   1-Serial Name.
   2-Column Name.
   3-Data Point.
3-Extend ActiveDataModelDecorator class to register Graph Model into Active Data Serive
4-Extend BaseActiveDataModel class to fire change event and use for creating resource / removing resource when  Active data Service will stop and start.
5-Build the Active Data Event which send to client to update the UI screen.
6-A class which will trigger change event.

Implementation Step

Step 1:First i have  created GraphData class which represent Graph Data for bar graph.Code is following

package com.blog.dvt.adf.graph.data;

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

    private int id;
    private String columnName;
    private double dataPoint;

    public GraphData(int id, String columnName, double dataPoint) {
        super();
        this.id = id;
        this.columnName = columnName;
        this.dataPoint = dataPoint;
    }


    public void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setColumnName(String columnName) {
        this.columnName = columnName;
    }

    public String getColumnName() {
        return columnName;
    }

    public void setDataPoint(double dataPoint) {
        this.dataPoint = dataPoint;
    }

    public double getDataPoint() {
        return dataPoint;
    }


    @Override
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if (!(object instanceof GraphData)) {
            return false;
        }
        final GraphData other = (GraphData)object;
        if (id != other.id) {
            return false;
        }
        if (!(columnName == null ? other.columnName == null :
              columnName.equals(other.columnName))) {
            return false;
        }
        if (Double.compare(dataPoint, other.dataPoint) != 0) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        final int PRIME = 37;
        int result = 1;
        result = PRIME * result + id;
        result =
                PRIME * result + ((columnName == null) ? 0 : columnName.hashCode());
        long temp = Double.doubleToLongBits(dataPoint);
        result = PRIME * result + (int)(temp ^ (temp >>> 32));
        return result;
    }
}

Step2:After that i have create a class which has List of Graph Data object.Later i have created the data control for same class and i have drag and drop list from data control into page as bar graph.

package com.blog.dvt.adf.graph.model;

import com.blog.dvt.adf.graph.data.GraphData;

import com.blog.dvt.adf.graphinterface.GraphInterface;

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

import javax.annotation.PostConstruct;

public class GraphModel {
    public GraphModel() {
        super();
    }
    private List<GraphData> graphData;

    public void setGraphData(List<GraphData> grpahData) {
        this.graphData = grpahData;
    }

    public List<GraphData> getGraphData() {
        if (graphData == null) {
            graphData = getDataForBarGraph();
        }
        return graphData;
    }

    private static List<GraphData> getDataForBarGraph() {
        List<GraphData> loadDataList = new ArrayList<GraphData>();
        GraphData g1 = new GraphData(0, "employee1", 10.0);
        GraphData g2 = new GraphData(1, "employee2", 20.0);
        GraphData g3 = new GraphData(2, "employee3", 30.0);
        GraphData g4 = new GraphData(3, "employee4", 40.0);
        GraphData g5 = new GraphData(4, "employee5", 50.0);
        loadDataList.add(g1);
        loadDataList.add(g2);
        loadDataList.add(g3);
        loadDataList.add(g4);
        loadDataList.add(g5);
        return loadDataList;
    }


}

Create the data control for this class and then drag and drop graphData List as bar graph.

Step 3:Till here it is just same as what we used to do for other component.Next step to create the data model for graph component which we need to associate with pages.

Step4:For creating Model class for bar graph we do require to extends ActiveDataModelDecorator class which has following two abstract  methods which we need to override .

1-public abstract oracle.adf.view.faces.bi.model.DataModel getModel() { }
2-public abstract oracle.adf.view.rich.model.ActiveDataModel getActiveDataModel() { }

In getModel()  need to return model which i have created above.

And getActiveDataModel need to return instance of the Active Data model.

My class name is GraphActiveCollectionModelDecorator and code is following


package com.blog.dvt.adf.decorator;

import com.blog.dvt.adf.activemodel.GraphActiveModelClass;
import com.blog.dvt.adf.activemodel.testing.TestingClass;
import com.blog.dvt.adf.graph.data.GraphData;
import com.blog.dvt.adf.graph.model.GraphModel;
import com.blog.dvt.adf.graphinterface.GraphInterface;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;

import javax.faces.application.Application;
import javax.faces.context.FacesContext;

import javax.faces.el.ValueBinding;

import oracle.adf.model.BindingContext;
import oracle.adf.model.binding.DCBindingContainer;
import oracle.adf.view.faces.bi.model.ActiveDataModelDecorator;
import oracle.adf.view.faces.bi.model.DataModel;
import oracle.adf.view.rich.event.ActiveDataEntry;
import oracle.adf.view.rich.event.ActiveDataUpdateEvent;
import oracle.adf.view.rich.model.ActiveDataModel;

import oracle.adfinternal.view.faces.activedata.ActiveDataEventUtil;
import oracle.adfinternal.view.faces.dvt.model.binding.graph.FacesGraphBinding;

import oracle.dss.util.DataSource;

public class GraphActiveCollectionModelDecorator extends ActiveDataModelDecorator implements GraphInterface {
    private GraphActiveModelClass _activeDataModel =
        new GraphActiveModelClass();
    private DataModel graphData = null;
    private oracle.dss.dataView.LocalXMLDataSource ds = null;
    int i = 5;
    int id = 5;
    int dataPoint = 40;

    public GraphActiveCollectionModelDecorator() {
        super();
    }

    public ActiveDataModel getActiveDataModel() {
        return _activeDataModel;
    }

    public DataModel getModel() {
        if (graphData == null) {
            DCBindingContainer dcBindings =
                (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
            FacesGraphBinding treeData =
                (FacesGraphBinding)dcBindings.getControlBinding("graphData");
            graphData = treeData.getDataModel();
            DCBindingContainer bc =
                (DCBindingContainer)FacesContext.getCurrentInstance().getApplication().evaluateExpressionGet(FacesContext.getCurrentInstance(),
                                                                                                             "#{bindings}",
                                                                                                             Object.class);
            TestingClass cc = (TestingClass)getBean();
            cc.setListener(this);
        }
        return graphData;
    }

    public void addingData() {
        GraphActiveModelClass asm = _activeDataModel;
        asm.graphDataChange();
        ActiveDataUpdateEvent event =
            ActiveDataEventUtil.buildActiveDataUpdateEvent(ActiveDataEntry.ChangeType.INSERT_AFTER,
                                                           asm.getCurrentChangeCount(),
                                                           new Object[] { i },
                                                           new Object[] { null },
                                                           new String[] { "id",
                                                                          "columnName",
                                                                          "dataPoint" },
                                                           new Object[] { id,
                                                                          "testing",
                                                                          dataPoint }); // the payload for the above attribute
        asm.notifyDataChange(event);
        id = id + 1;
        i = i + 1;
        dataPoint = dataPoint + 10;
    }

    public void updatingData() {
        GraphActiveModelClass asm = _activeDataModel;
        asm.graphDataChange();
        ActiveDataUpdateEvent event =
            ActiveDataEventUtil.buildActiveDataUpdateEvent(ActiveDataEntry.ChangeType.UPDATE,
                                                           asm.getCurrentChangeCount(),
                                                           new Object[] { 1,
                                                                          0 },
                                                           new Object[] { null },
                                                           new String[] { "dataPoint" },
                                                           new Object[] { 40 }); // the payload for the above attribute
        asm.notifyDataChange(event);
    }

    public void deletiangData() {
        GraphActiveModelClass asm = _activeDataModel;
        asm.graphDataChange();
        ActiveDataUpdateEvent event =
            ActiveDataEventUtil.buildActiveDataUpdateEvent(ActiveDataEntry.ChangeType.REMOVE,
                                                           asm.getCurrentChangeCount(),
                                                           new Object[] { 1,
                                                                          0 },
                                                           new Object[] { null },
                                                           new String[] { "id",
                                                                          "columnName",
                                                                          "dataPoint" },
                                                           new Object[] { 0,
                                                                          "testing",
                                                                          10.0 }); // the payload for the above attribute
        asm.notifyDataChange(event);
    }

    public Object getBean() {
        FacesContext context = FacesContext.getCurrentInstance();
        Application app = context.getApplication();
               ValueBinding binding = app.createValueBinding("#{testingClass}");
        Object value = binding.getValue(context);
        return value;
    }
}


Model is ready and need to use in jspx page.

Step5:Above getActiveDataModel () method need to return our active data model reference hence i have create one class where i extends BaseActiveDataModel class and code is following

package com.blog.dvt.adf.activemodel;

import java.util.Collection;
import java.util.concurrent.atomic.AtomicInteger;

import oracle.adf.view.rich.activedata.BaseActiveDataModel;
import oracle.adf.view.rich.event.ActiveDataUpdateEvent;

public class GraphActiveModelClass extends BaseActiveDataModel {

    protected void startActiveData(Collection<Object> rowKeys,
                                   int startChangeCount) {
        _listenerCount.incrementAndGet();
    }

    @Override
    protected void stopActiveData(Collection<Object> rowKeys) {

    }

    @Override
    public int getCurrentChangeCount() {
        return changeCounter.get();
    }

    public void graphDataChange() {
        changeCounter.incrementAndGet();
    }

    public void notifyDataChange(ActiveDataUpdateEvent event) {
      fireActiveDataUpdate(event);
    }
    private final AtomicInteger changeCounter = new AtomicInteger();

    private final AtomicInteger _listenerCount = new AtomicInteger(0);
}

Step 6:Need to register Model class in adfc-confg.xml file with session scope.

<?xml version="1.0" encoding="windows-1252" ?>
<adfc-config xmlns="http://xmlns.oracle.com/adf/controller" version="1.2">
  <managed-bean id="__1">
    <managed-bean-name id="__4">graphActive</managed-bean-name>
    <managed-bean-class id="__2">com.blog.dvt.adf.decorator.GraphActiveCollectionModelDecorator</managed-bean-class>
    <managed-bean-scope id="__3">session</managed-bean-scope>
  </managed-bean>
  <managed-bean id="__8">
    <managed-bean-name id="__7">testingClass</managed-bean-name>
    <managed-bean-class id="__5">com.blog.dvt.adf.activemodel.testing.TestingClass</managed-bean-class>
    <managed-bean-scope id="__6">session</managed-bean-scope>
    <managed-property id="__13">
      <property-name id="__12">listener</property-name>
      <value id="__14">#{graphActive}</value>
    </managed-property>
  </managed-bean>
</adfc-config>

Step7:Jspx code is following

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
          xmlns:dvt="http://xmlns.oracle.com/dss/adf/faces">
  <jsp:directive.page contentType="text/html;charset=UTF-8"/>
  <f:view>
    <af:document id="d1">
      <af:messages id="m1"/>
      <af:form id="f1">
        <dvt:barGraph id="barGraph1" value="#{graphActive}"
                      subType="BAR_VERT_CLUST" shortDesc="testing">
          <dvt:background>
            <dvt:specialEffects/>
          </dvt:background>
          <dvt:graphPlotArea/>
          <dvt:seriesSet>
            <dvt:series/>
          </dvt:seriesSet>
          <dvt:o1Axis/>
          <dvt:y1Axis/>
          <dvt:legendArea automaticPlacement="AP_NEVER"/>
        </dvt:barGraph>
      </af:form>
    </af:document>
  </f:view>
</jsp:root>

Image is following



In GraphActiveCollectionModelDecorator class i have written code for insert/update/delete build event which you can use for inserting ,updating and deleting the data value from graph.


Link is following :

1-https://docs.google.com/open?id=0B8cP4jZuxLlXN1VFQXlKUlZZbDg

PS:In Example i am just adding new data in bar graph  but in Testing Class which is responsible for calling adding/updating/deleting  method where you can change with updating and deleting method calling.In Updating and Deleting case it do require to pass correct row key.For any bar the row key will column number and zero for series since here i have only one series hence i am passing 1,0 as key value.

Thanks
Prateek

Monday, November 12, 2012

Oracle Coherence with Active Data Service

Hi ,

Use Case :Need to show latest records into af:table with use of oracle coherence.

Class Description :

The following class which i used to achieve my requirement .

1-TableActiveCollectionModelDecorator
    This class used for providing the model data for af:table
    Extends ActiveCollectionModelDecorator 

2-TableActiveModelClass
   This class extends BaseActiveDataModel

3-CoherenceClass
   This class use to put the data into oracle coherence

4-Interface TableInterface for listen Map listener 

The class and interface relationship is depicted in following picture

UI description :

Here i used af:table as UI component to show the latest data.

I have been working on a project where i need to show the latest data on UI .For this we are using following technology.

1-Active data service
2-And oracle coherence

Since this bit tricky and tough to understand so for this i have divided my post under following  parts

Step 1-In first part will explain active data service configuration into the application.
Step 2-In second part will explain  oracle coherence for maintaining data in memory cache.
Step 3-In third part will explain communication between between  oracle coherence and Active data Service.
Step 4-Registration of the bean into adfc-config.xml 
Step5-Doing following operation into oracle coherence cache.
 1-Adding new record into cache
 2-update records into cache
 3-delete records into cahce 

So let me explain each individual point in details

Step 1-In first part will explain active data service configuration into the application.

1-You require to configure Active Data Service  in the adf-config.xml.In adf-config.xml file need to register communication transport details and  need to create new property file name as adf-config.properties file .

i)ADD following code in adf-config.xml

<?xml version="1.0" encoding="utf-8" ?>
<adf-config xmlns="http://xmlns.oracle.com/adf/config"
            xmlns:ads="http://xmlns.oracle.com/adf/activedata/config">
  <ads:adf-activedata-config xmlns=
                            "http://xmlns.oracle.com/adf/activedata/config">
    <transport>long-polling</transport>
    <latency-threshold>10000</latency-threshold>
    <keep-alive-interval>10000</keep-alive-interval>
    <polling-interval>3000</polling-interval>
    <max-reconnect-attempt-time>1500000</max-reconnect-attempt-time>
    <reconnect-wait-time>10000</reconnect-wait-time>
  </ads:adf-activedata-config>
</adf-config>


ii)First create services folder under .adf/META-INF directory and then create property file name  adf-config.properties add following code in adf-config.properties file

http\://xmlns.oracle.com/adf/activedata/config=oracle.adfinternal.view.faces.activedata.ActiveDataConfiguration$ActiveDataConfigCallback


*Be careful all the above line should be in  one single line.

2-Since here i am using af:table component for Active data service so first class which we do require to extends is ActiveCollectionModelDecorator.
Here i am using  ActiveCollectionModelDecorator class however you can also use ActiveDataModel class .
 Code is following

package com.backing.bean.ads;

import com.backing.bean.coherence.CoherenceClass;
import com.backing.bean.coherence.Example;
import com.backing.bean.data.TableData;
import com.backing.bean.interfacee.TableInterface;
import com.backing.bean.model.TableActiveModelClass;

import java.util.List;

import javax.el.ExpressionFactory;
import javax.el.ValueExpression;

import javax.faces.context.FacesContext;

import oracle.adf.view.rich.event.ActiveDataEntry;
import oracle.adf.view.rich.event.ActiveDataUpdateEvent;
import oracle.adf.view.rich.model.ActiveCollectionModelDecorator;
import oracle.adf.view.rich.model.ActiveDataModel;

import oracle.adfinternal.view.faces.activedata.ActiveDataEventUtil;

import org.apache.myfaces.trinidad.model.CollectionModel;
import org.apache.myfaces.trinidad.model.SortableModel;

public class TableActiveCollectionModelDecorator extends ActiveCollectionModelDecorator  {

    private TableActiveModelClass _activeDataModel =
        new TableActiveModelClass();
    List<TableData> getTableDataList = null;
    private CollectionModel _model = null;

    public TableActiveCollectionModelDecorator() {
        super();
    }

    public ActiveDataModel getActiveDataModel() {
        return _activeDataModel;
    }

    protected CollectionModel getCollectionModel() {
        if (_model == null) {
            FacesContext ctx = FacesContext.getCurrentInstance();
            ExpressionFactory ef = ctx.getApplication().getExpressionFactory();
            ValueExpression ve =
                ef.createValueExpression(ctx.getELContext(), "#{coherenceClass}",
                                         CoherenceClass.class);
            CoherenceClass context =
                (CoherenceClass)ve.getValue(ctx.getELContext());
            getTableDataList = context.getTableDataList();
            _model = new SortableModel(getTableDataList);
        }
        return _model;
    }
 }

*Here coherence class is responsible to fetch data from coherence and return into this class.When the page if load first time getCollectionModel() method will called and return data back to UI.

Here following method are override

1-public ActiveDataModel getActiveDataModel() {}
2- public CollectionModel getCollectionModel(){}

3-Second class which is require to extends  BaseActiveDataModel class moreover  this class is also very important class.Code is following

package com.backing.bean.model;

import java.util.Collection;

import java.util.concurrent.atomic.AtomicInteger;

import oracle.adf.view.rich.activedata.BaseActiveDataModel;
import oracle.adf.view.rich.event.ActiveDataUpdateEvent;
import oracle.adf.view.rich.model.ActiveCollectionModelDecorator;
import oracle.adf.view.rich.model.ActiveDataModel;

import org.apache.myfaces.trinidad.model.BaseMenuModel;
import org.apache.myfaces.trinidad.model.CollectionModel;

public class TableActiveModelClass extends BaseActiveDataModel {
    @Override
    protected void startActiveData(Collection<Object> rowKeys,
                                   int startChangeCount) {

    }
   @Override
    protected void stopActiveData(Collection<Object> rowKeys) {
    }
@Override
    public int getCurrentChangeCount() {
        return changeCounter.get();
    }
    public void prepareDataChange() {
        changeCounter.incrementAndGet();
    }
    public void notifyDataChange(ActiveDataUpdateEvent event) {

        fireActiveDataUpdate(event);
    }
    private final AtomicInteger changeCounter = new AtomicInteger();
}


Although here i am not doing any thing in the startActiveData and stopActiveData but it is used to seed and remove the resource.

Above are steps to implements Active data service and following are for oracle coherence

Step 2-In second part will explain  oracle coherence for maintaining data in memory cache.

1-First need to add the coherence.jar jar file into application path. coherence.jar is already available in jdeveloper installation folder
 Location is following
 oracle installation  folder name\oracle_common\modules\oracle.coherence 

2-Created class name as CoherenceClass where i have done initialization for Name  Cache as following in static block


    static {
        nameCache = CacheFactory.getCache(CACHE_NAME);
    }


3-In constructor of  CoherenceClass load the data form method  and add in the oracle coherence as following


    public CoherenceClass() {
        CacheFactory.ensureCluster();
        NamedCache nc = CacheFactory.getCache(CoherenceClass.CACHE_NAME);
        nc.addMapListener(this);
        if (nc.size() == 0) {
            nc.putAll(loadDataFromCoherence());
        }
    }

    private static Map loadDataFromCoherence() {
        //This are my friends name
        Map loadDataMap = new HashMap();
        loadDataMap.put("C0", new TableData(0L, "Prateek"));
        loadDataMap.put("C1", new TableData(1L, "Abhishek"));
        loadDataMap.put("C2", new TableData(2L, "Satyendra"));
        loadDataMap.put("C3", new TableData(3L, "Ramesh"));
        loadDataMap.put("C4", new TableData(4L, "Anoop"));
        loadDataMap.put("C5", new TableData(5L, "Jamal"));
        loadDataMap.put("C6", new TableData(6L, "Laljeet"));
        loadDataMap.put("C7", new TableData(7L, "Hariom"));
        loadDataMap.put("C8", new TableData(8L, "Rajesh"));
        return loadDataMap;
    }


4-In next step i required to implements interface name MapListener which has following method  to catch the event.


    public void entryInserted(MapEvent mapEvent) {  }

    public void entryUpdated(MapEvent mapEvent) }

    public void entryDeleted(MapEvent mapEvent) {}


If we add/remove/delete any things from same cache it will automatically trigger this method accordingly 

5-So in the same class i have implemented MapListener and override above three method .

Step 3-In third part will explain communication between between  oracle coherence and Active data Service. 

Here i done with Active data service and oracle coherence.Although we do require communication between coherence and ads .

For providing communication between these two i have created one interface and step are following

1-Created an interface name as TableInterface which has following method

    public void entryInCoherence(Integer rowKey, TableData tableData);

    public void updateInCoherence(Integer rowKey, TableData tableData);

    public void deleteInCoherence(Integer rowKey, TableData tableData);


2-implemetated this interface with same class which extends  ActiveCollectionModelDecorator class and override all the method code are following


      public void entryInCoherence(Integer rowKey, TableData tableData) {
        if (rowKey != null) {
            TableActiveModelClass asm = _activeDataModel;
            asm.prepareDataChange();
            ActiveDataUpdateEvent event =
                ActiveDataEventUtil.buildActiveDataUpdateEvent(ActiveDataEntry.ChangeType.INSERT,
                                                               asm.getCurrentChangeCount(),
                                                               new Object[] { rowKey },
                                                               new Object[] { null },
                                                               new String[] { "id",
                                                                              "name" },
                                                               new Object[] { tableData.getId(),
                                                                              tableData.getName() });
            asm.notifyDataChange(event);
        }
    }

    public void updateInCoherence(Integer rowKey, TableData tableData) {
        if (rowKey != null) {
            TableActiveModelClass asm = _activeDataModel;
            asm.prepareDataChange();
            ActiveDataUpdateEvent event =
                ActiveDataEventUtil.buildActiveDataUpdateEvent(ActiveDataEntry.ChangeType.UPDATE,
                                                               asm.getCurrentChangeCount(),
                                                               new Object[] { rowKey },
                                                               new Object[] { null },
                                                               new String[] { "id",
                                                                              "name" },
                                                               new Object[] { tableData.getId(),
                                                                              tableData.getName() });
            asm.notifyDataChange(event);
        }
    }

    public void deleteInCoherence(Integer rowKey, TableData tableData) {
        TableActiveModelClass asm = _activeDataModel;
        asm.prepareDataChange();
        ActiveDataUpdateEvent event =
            ActiveDataEventUtil.buildActiveDataUpdateEvent(ActiveDataEntry.ChangeType.REMOVE,
                                                           asm.getCurrentChangeCount(),
                                                           new Object[] { rowKey },
                                                           new Object[] { null },
                                                           new String[] { "id",
                                                                          "name" },
                                                           new Object[] { tableData.getId(),
                                                                          tableData.getName() });

        asm.notifyDataChange(event);
    }




Step 4-Registration of the bean into adfc-config.xml 



<managed-bean id="__2">
    <managed-bean-name id="__1">tableActive</managed-bean-name>
    <managed-bean-class id="__4">com.backing.bean.ads.TableActiveCollectionModelDecorator</managed-bean-class>
    <managed-bean-scope id="__3">session</managed-bean-scope>
  </managed-bean>
  <managed-bean id="__26">
    <managed-bean-name id="__25">coherenceClass</managed-bean-name>
    <managed-bean-class id="__23">com.backing.bean.coherence.CoherenceClass</managed-bean-class>
    <managed-bean-scope id="__24">session</managed-bean-scope>
    <managed-property id="__28">
      <property-name id="__27">listener</property-name>
      <value id="__29">#{tableActive}</value>
    </managed-property>
  </managed-bean>



Step5-Doing following operation into oracle coherence cache.

I have created TestingClass class for doing add/delete/update into cache i have created one main class which has following code.
 package com.backing.bean.coherence;

import com.backing.bean.data.TableData;

import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;

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

    public static void main(String[] args) {
        //here only add new record line is commented
        //following checking the update and delete please remove the comment
        NamedCache nc = CacheFactory.getCache(CoherenceClass.CACHE_NAME);
        //adding  new record
        nc.put("PK1", new TableData(1001L, "PrateekShaw"));
        //updatring record
        // nc.put("PK1", new TableData(1001L, "PrateekKumarShaw"));
        //deleting record
        // nc.remove("PK1");//Pass the key
    }
}





So in above code if you run after running the  page since only add line is not commented  so it will add the new record into cache .
1-Aftering adding records in cache


2-After  updating records


3-After deleting records




Code is present at following location

https://docs.google.com/open?id=0B8cP4jZuxLlXbWcyU0RVejc5b28

I have to explain more in details which i know but due to less time i have to stop here but  later sure i will update this post if possible.

However this is just POC to understand communication between oracle coherenernce and ADS.


Reference :

1-http://biemond.blogspot.in/2009/12/adf-data-push-with-active-data-service.html
2-http://matthiaswessendorf.wordpress.com/2010/01/07/adf%E2%80%99s-active-data-service-and-scalar-data-like-activeoutputtext/
3-Oracle Fusion Developer Guide

Thanks
Prateek

Monday, October 15, 2012

Active Data Service (ADS)


Active Data Service :

As name imply active data service is used to show the latest data on UI.
The main example is stock market where the value of the share is always changing therefore provide this type of feasibility oracle has introduced a mechanize which is called Active Data Service.

 But before going to jump into the details about Active Data Service i would like to put some light on why do we really need active data service and how it is work in real scenario.

All the real time application now days are based on client server architecture. So there is two things
1-Request
2-Response

Always request is initiated by client for to performing  operation on server and server will response as soon as possible .as long as the response come there is no any communication left  between server and client.
Following picture depicts the relation ship between server and client .

So this is all about the server and client relation and about Hyper text transfer protocol .Let come on actual topic .
To be honest the Active Data Service is huge and also it is bit complex.That is reason why i thought  to start with simple.Since oracle has given one component that support the Active Data Service without doing any thing.By the way oracle also has give other component that support the Active Data Service but that require configuration and coding to make them work.

So for understanding the Active data service it is good to first understand about af:poll component which is based on the Active data Service however you can direct start  learning  the Active data service without knowing the af:poll  components.

af:poll document is at following location

1-http://jdevadf.oracle.com/adf-richclient-demo/docs/tagdoc/af_poll.html

af:poll will run automatically and run at certain period of time or  it will run periodically.

The server and client communication can happens following three type which are following

1-Push  as know as HTTP stream 
2-Poll 
3-Long poll

So af:poll is based on poll communication.Where client always should request to server after some period of time.
For one request server will response so there is no any more communication left  and client need to initiate  again new request.
In my next post i will go more depth in about above maintained approach.

Here it is clear that af:poll is based on the Poll approach.

For understanding the af:poll i have implemented following way

1-First i have created a page where i have inserted  af:table and af:poll component.

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
  <jsp:directive.page contentType="text/html;charset=UTF-8"/>
  <f:view>
    <af:document id="d1">
      <af:form id="f1">
        <af:table var="row" value="#{pollApplication.tableValue}"
                  rowBandingInterval="0" id="t1"
                  binding="#{pollApplication.richTable}">
          <af:column sortable="false" headerText="ColumnHearder" id="c2">
            <af:outputText value="#{row.columnValue}" id="ot1"/>
          </af:column>
          <af:column sortable="false" headerText="TimeStamp" id="c1">
            <af:outputText value="#{row.timeStamp}" id="ot2"/>
          </af:column>
        </af:table><af:poll id="p1" pollListener="#{pollApplication.pollListenerMethod}"/>
      
      </af:form>
    </af:document>
  </f:view>
</jsp:root>

And i am passing the table data using table through backing bean and also i attached poll event with backing bean
2-Passing value through backing bean
    private List<TableData> tableValue;
    private RichTable richTable;

    public void setTableValue(List<TableData> tableValue) {
        this.tableValue = tableValue;
    }

    public List<TableData> getTableValue() {
        if (tableValue == null) {
            tableValue = new ArrayList<TableData>();
            for (int i = 0; i < 4; i++) {
                TableData tableData = new TableData();
                tableData.setColumnValue(i + "Column" +
                                         System.currentTimeMillis());
                tableData.setTimeStamp(System.currentTimeMillis());
                tableValue.add(tableData);
            }
        }
        return tableValue;
    }

    public void pollListenerMethod(PollEvent pollEvent) {
        AdfFacesContext.getCurrentInstance().addPartialTarget(richTable);
    }

    public void setRichTable(RichTable richTable) {
        this.richTable = richTable;
    }

    public RichTable getRichTable() {
        return richTable;
    }

Here in backing bean i have refreshing whole adf table again and again in the pollListenerMethod method which automatically trigger after every five seconds
Although user has option to increase/decrease  interval value as their need by the way default interval is 5000 mill second.

This sample example which is based on af:poll and af:poll is based on active data service .In Poll client will call server periodically based on what interval is given .

Above code is example how Poll is working.Here client will call the server at some period of time.
Nevertheless in my up coming post i  would like to put more information on active data service.


Source code is present at following link
1-https://docs.google.com/open?id=0B8cP4jZuxLlXRTRyVnVYeTdSWW8



Disadvantage :
1-It is always call server which extra over head on server.
2-This approach is just for understanding about af:poll.If you executing binding again regardless if there is any change or not  then it is  not suitable .
3-Refereshing the whole pages or whole table obviously not correct.

PS:
1-For using af:poll does  not require any extra coding since Adf servlet which is added  by default in web.xml will take care.no extra code .
2-Through client side java script it will call server periodically .

Monday, September 24, 2012

Oracle Adf Became free (Open Source not fully )

Hi All,

I know this is making allot of buzz on internet today so that why i have also decided to make a post on the same.

You can get more information at following link

1-http://www.oracle.com/technetwork/developer-tools/adf/overview/adfessentials-1719844.html
2-https://blogs.oracle.com/smuenchadf/entry/free_version_of_oracle_application


BTW Following part which they make open source

1-BC component
2-ADF faces
3-Binding Layer (JSR 227 )
4-ADF Controller
5-DVT Component 

Although i also want to put some more point here ,they make the ADF open source that is true but if you have weblogic server license already then still you do not require to get any license from oracle to use ADF in production .


SO here is deal either you are fare enough to use the ADF with Glass Fish or forget this open source myth.

Since they have not make security as open source and if you are willing to take then you should have to get license from oracle.So here we can understand oracle why they have not made security open sources because security is only work with weblogic server mean it is compatible with weblogic and they are never ever going to make weblogic free .

So i have here mixed response for this announcement.


Thanks
Prateek

Saturday, September 15, 2012

Exception Handling In Adf (Part 1.1)

Hi All,

Although in my  first Exception Handling post I have explained the exception handling approach in the model layer however here I also would like  to add some more approach in same model layer (binding layer).

We can handle Exception Handling in Model layer as following ways

1-For Single Application and handle as global for model layer(Binding layer) :
(If you have only on DataBinding.cpx file )
Create the Class which extend DCErrorHandlerImpl  and register with DataBinding.cpx file.It means all the page def file which is associated with this DataBinding.cpx  file if throws any exception then Extends Class is going to catch the exception .
So this approach is work whole in model layer regardless what ever  page def is associated with the DataBinding.cpx .

2-Only for individual page def file (Binding layer):
Second Approach is going to handle the exception only for  one page where we register our custom class as a ControllerClass .

3-For N number of application and handle as global for all  model layer(Binding layer) :
(If you have only DataBinding.cpx file or more than one ) . (Top most application has Error Handler)
Suppose if you  have a big application which contains N number of projects.Therefore each individual project have their own DataBinding.cpx file.If you implement the first approach you need to create N number file for each individual Class file which extends DCErrorHandlerImlp class.So over come this type of issue Oracle Adf provide one more type of Model layer Exception handling.Where you need to extends one ADF life cycle class,One JSF life cycle class and need to register the custom JSF life cycle class into faces-config.xml.
So in this case if exception thrown in any application but from model layer(binding layer) then  custom class will going to catch the exception .

After reading above points ,I am sure it will give the clear ideas of Exception Handling Approach in Model Layer.

If your top most application has error handler register then you do not required to inject Error handler class using above approach.

Let me explain above point into details

1-For Single Application and handle as global for model layer : Since my last exception handling post I have already explain this approach .

2-Only for individual page def file : You can handle exception in model layer for only one single page .For implementing this approach do following step

i-Create the class and extends with FacesPageLifecycle class
ii- override following method 
public void reportErrors(PageLifecycleContext pageLifecycleContext){};
iii-Then register this newly created class into page def file in ControllerClass  file .
iv-This method always being called when any exception thrown from same page.

3-For N number of application and handle as global for all model layer (Binding Layer):  This approach will help full if you dealing with a large application which contains n number of project.And you do not want each individual application owner to implement the exception handling.

Let me explain my use case where we have implemented this approach ,

We have a  very large application so  we have divided our large application into  simple module .and after that we have created on main application where we add this application as jar or war.It mean through this main application we will access our module.

Hence we have implemented this approach.

So for this we have created one new application where we have written all exception handling related code.And after that we have created the adf jar file which we consumed  into our main application.

Step are following .
1-Create the class and extends with DCErrorHandlerImpl
2-Override the public void reportException(DCBindingContainer bc, Exception ex) .


package com.prateek.blog.view.exception;

import oracle.adf.model.binding.DCBindingContainer;
import oracle.adf.model.binding.DCErrorHandlerImpl;

import oracle.jbo.JboException;

public class CustomExceptionHandler extends DCErrorHandlerImpl {
    public CustomExceptionHandler() {
        super(true);
    }

    @Override
    public void reportException(DCBindingContainer dCBindingContainer,
                                Exception exception) {

        if (exception instanceof JboException) {
            //By default all exception which are coming from Model layer all are instance of JboException
            //here just i am try to skip the exception to report to super class which is DCErrorHandlerInpl
            //we can write our own logic
            // if the exception came of model then it always go through this if condition
        } else {
            super.reportException(dCBindingContainer, exception);
        }

    }

    private void disableAppendCodes(Exception ex) {
        if (ex instanceof JboException) {
            JboException jboEx = (JboException)ex;
            jboEx.setAppendCodes(false);
            Object[] detailExceptions = jboEx.getDetails();
            if ((detailExceptions != null) && (detailExceptions.length > 0)) {
                for (int z = 0, numEx = detailExceptions.length; z < numEx;
                     z++) {
                    disableAppendCodes((Exception)detailExceptions[z]);
                }
            }
        }
    }

    @Override
    public DCErrorMessage getDetailedDisplayMessage(BindingContext bindingContext,
                                                    RegionBinding regionBinding,
                                                    Exception exception) {
        return super.getDetailedDisplayMessage(bindingContext, regionBinding,
                                               exception);
    }

    @Override
    public String getDisplayMessage(BindingContext bindingContext,
                                    Exception exception) {
        return super.getDisplayMessage(bindingContext, exception);
    }

    @Override
    protected boolean skipException(Exception exception) {
        return super.skipException(exception);
    }

}

*This code same as my last post.User need to customize base on their requirements.

3- Then need to create custom page life cycle class that extends  FacesPageLifecycle
4-Over ride the Prepare model method  where we need to register newly create customer exception handler class into the setErrorHandler method
public void prepareModel(LifecycleContext ctx)
{
if (!(ctx.getBindingContext().getErrorHandler() instanceof ModelExceptionHandlerClass)) { ctx.getBindingContext().setErrorHandler(new ModelExceptionHandlerClass(true));
}
super.prepareModel(ctx);
 }
here ModelExceptionHandlerClass class my custom exception handler class.

5-Then need to create custom listener class where need to register newly created life cycle class .
6-For this need to extends ADFPhaseListener class .
7-Override  protected PageLifecycle createPageLifecycle(){}

@Override protected PageLifecycle createPageLifecycle() { return new FacesPageLifecycleBean(); }

8-Need to register above class into faces-config.xml file under life cycle property.

Code of the above implementation is following
https://docs.google.com/open?id=0B8cP4jZuxLlXTnRIMkxaWURhazg

This post explain  different type of approach for handling exception in model layer(binding layer).

 Thanks
Prateek Shaw.